Update primefaces parent component, without re-render its datatable child - jsf

I want to update the parent component (an outputpanel) of a datatable without the datatable itself (lazy loaded) so that its#load method will not get triggered (it performs a very heavy API request so I do not want it to be called for no reason).
So far I have tried to use the :not() operator from the update event but when I do so, the parent component does not update itself too, why that strange behaviour? Code example below:
Parent component I want to be updated apart from its datatable child
<h:form id="myForm">
<p:outputPanel id="parentContainer" styleClass="fullHeight parent"
style="display:#{(myBean.showCreateForm == false)?'block;':'none'}">
<p:dataTable id="myDatatable" lazy="true"
styleClass="exclude" ...
</p:dataTable>
</p:outputPanel>
</h:form>
Button updating the upper form
// this button toggles the myBean.showCreateForm variable show it toggles the upper div
<p:commandButton update="#(.parent :not(.exclude))" partialSubmit="true" ajax="true">
The behaviour I would like to have from the code above is:
1)On click of the button I want to toggle the parentContainer div but 2)do not re-render its datatable through the ajax update and call its #load method (since it is lazy loaded).
Unfortunately when I exclude the datatable through the :not selector, the parent element (parentContainer) does not also update/toggles.
Is there any way to achieve my case?

Related

Re-Render PrimeFaces elements after certain events

I want to conditionally render my menuitem depending on which element I invoke my menu on.
Only problem is: The menuitem renders the moment the xhtml is loaded. Because of that, I'll only get "null" for my selected element.
Of course I can catch that by saying "if it`s null, just render it", but the real problem is that, once rendered, the menuitem stays rendered.
Is there any way to render/re-render my menuitem right AFTER I open the menu(by then I'll have the information needed)?
I've tried several ways to aquire this:
remoteCommand (I don't need to invoke any bean, so it seems to be the wrong tool)
PageReload(Will obviously close my menue)
Ajax(Might work, but I just started learning it -> In this case it did nothing)
EDIT:
Ajax does work. I've updated the code. Right now im re-rendering the contextMenue once I've selected an item, so the children will call their respective beans again and render correctly.
Only flaw is:
This takes for to long (guess this would lead to another question...)
I don't want to re-render the menue, but the children! If I re-render the children directly, ajax can't find them by id anymore, so it will crash.
Any ideas?
test.xhtml
<p:contextMenu for="treeId" ajax="false" id="openSP">
<p:menuitem value="Example" ajax="false"
action="#{MyClass.method}"
rendered="#{MyClass2.renderItem}" >
</p:menuitem>
</p:contextMenu>
<p:treeTable id="test"
...
<f:ajax event="select" render="openSP" />
...
</p:treeTable>

What is the correct way to use RequestScoped Bean and rendered attribute?

does anybody know how to use RequestScoped bean together with rendered attribute in jsf? The rendered attribute is evaluated before applyValues phase and therefore is not correctly evaluated. I don't want to preserve any state. The example could be an outputPanel with a datatable and a button. The datatable gets a list of values. The wrapping outputPanel has the rendered attribute like:
<p:outputPanel rendered="#{not empty requestScopedBean.dataList}">
<p:datatable value="#{requestScopedBean.dataList}">
...
</p:datatable>
<p:commandButton action="#{requestScopedBean.someAction}" />
</p:outputPanel>
After loading the page and clicking on the button, nothing happens, because the view is restored and expressions are evaluated - the bean does have an empty datalist and therefore the panel should not be rendered. This causes that the action method is not even called - because the button doesn't exist.
If you're not interested in having a filled data table at that moment, just add an extra check in rendered attribute if the command button of interest has been invoked. You can do that by checking the presence of button's client ID in request parameter map.
<p:outputPanel rendered="#{not empty requestScopedBean.dataList or not empty param[someButton.clientId]}">
...
<p:commandButton binding="#{someButton}" ... />
</p:outputPanel>
See also:
How to let validation depend on the pressed button?

Cannot call action methods on RequestScoped Bean from tabView [duplicate]

does anybody know how to use RequestScoped bean together with rendered attribute in jsf? The rendered attribute is evaluated before applyValues phase and therefore is not correctly evaluated. I don't want to preserve any state. The example could be an outputPanel with a datatable and a button. The datatable gets a list of values. The wrapping outputPanel has the rendered attribute like:
<p:outputPanel rendered="#{not empty requestScopedBean.dataList}">
<p:datatable value="#{requestScopedBean.dataList}">
...
</p:datatable>
<p:commandButton action="#{requestScopedBean.someAction}" />
</p:outputPanel>
After loading the page and clicking on the button, nothing happens, because the view is restored and expressions are evaluated - the bean does have an empty datalist and therefore the panel should not be rendered. This causes that the action method is not even called - because the button doesn't exist.
If you're not interested in having a filled data table at that moment, just add an extra check in rendered attribute if the command button of interest has been invoked. You can do that by checking the presence of button's client ID in request parameter map.
<p:outputPanel rendered="#{not empty requestScopedBean.dataList or not empty param[someButton.clientId]}">
...
<p:commandButton binding="#{someButton}" ... />
</p:outputPanel>
See also:
How to let validation depend on the pressed button?

ui:repeat with a list sending right object to a p:dialog

I currently have a giant ui:repeat. Within this ui:repeat, some of the repeated objects have a url to a popup image associated with them. When someone clicks display under that particular object, I need the url to popup in a p:dialog.
<ui:repeat var="thing" value="#{bean.thingList}">
<p:commandLink value="details" onclick="miniImage.show();"
update=":#{p:component('chart')}"
action="#{bean.setCurrentImg(thing.imageUrl)}"
rendered="#{thing.includeImage}">
</p:commandLink>
</ui:repeat>
and at the bottom of the page:
<p:dialog id="chart" widgetVar="miniImage" >
<h:graphicImage value="#{bean.currentImg}"/>
</p:dialog>
And in the backing bean I tried using a simple setter and getter for currentImg.
I am a bit confused on this now and would like to accomplish this without having to submit the entire form as well. Any help is greatly appreciated.
If you're using PrimeFaces 3.3 or newer, you could just add partialSubmit="true" to the command component. You can then control the to-be-processed components in process attribute. In this particular case, just the current component (the command component itself) is sufficient, thus so process="#this":
<p:commandLink ... process="#this" partialSubmit="true" />
This way only the request parameters which are really necessary for the process will be sent.
Unrelated to the concrete problem, I suggest to use oncomplete instead of onclick to open the dialog. Otherwise the dialog is opened before update takes place and may cause poor user experience as the enduser would see the image instantly changing.

PrimeFaces dialog validation errors

What i want to do is like basic row selection example at Primefaces showcase(http://www.primefaces.org/showcase/ui/datatableRowSelectionByColumn.jsf) I want to update my datatable's row. The problem is when i click to update button at datatable, dialogbox appears with validation errors.
Second thing is what is the order of method execution times.(action-update-onclick-f:setPropertyActionListener)
<p:commandButton id="updateButtonId"
action="#{myController.showCompanyEditPanel}"
update=":tabView:companyForm:companyEditPanel"
onclick="companyDialog.show()"
icon="ui-icon-pencil" title="update">
<f:setPropertyActionListener value="#{company}" target="#{myController.selectedCompany}" />
</p:commandButton>
<p:dialog id="editCompanyDialogId" header="CompanyEdit" widgetVar="companyDialog" resizable="false">
<p:panel id="companyEditPanel" >
//some stuff here
</p:panel>
</p:dialog>
You seem to be missing a major point of using a <p:commandButton> here, as well as seem to be mixing client-side and server-side events.
First on <p:commandButton>. This component is designed to POST (partial) form data to the current URL, do business job in action(listener) method and return updated components / perform navigation. You can of course 'attach' JavaScript events to all those attributes.
Second, onclick, oncomplete, and other on... attribute are corresponding to some client-side events. In particular, onclick function is triggered when button was clicked, oncomplete function is called when DOM was updated after the AJAX call, i.e. the elements specified in <p:ajax update="..."> or simply in update="..." attribute of <p:commandButton>.
Third, all action listeners (thus, actionListener attribute, <f:actionListener> tag, <f:setPropertyActionListener> tag) will be executed right in the order they are specified in your tag, see this answer for more elaboration. The last one to be executed is action method, after which response is sent back.

Resources