Primefaces : update dialog content and keep it open - jsf

I'm working with JSF and PrimeFaces, and I can't handle the following situation:
I have a dialog, and I placed a dataTable on it. In one of the cells of the table I would like to display given data in 3 different ways, and I'd like to switch between them. So far I managed to switch between these rendering types via commandLink, but my problem is that when I click on one of the 3 links, the dialog closes! Can I update the content of the dialog, and be able to keep it open the same time? (I'm updating which render type to use via myMethod)
my commandLink looks like this:
<p:commandLink id="id" update=":myForm:myDialog" ajax="false"
action="#{myBean.myMethod}" oncomplete="dialog.show()">
If i don't use the ajax=false attribute, the method is not called, and I also tried imediate=true, but that's not it either.

You need to define an p:outputPanel inside your dialog and update the outputpanel, not the dialog itself (that's why your dialog closes):
<p:dialog id="myDialog" ...>
<p:outputPanel id="myOutputPanel">
... your dialog content goes here
</p>
</p:dialog>
and change your commandlink
<p:commandLink id="id" update=":myForm:myDialog:myOutputPanel" ajax="true"
action="#{myBean.myMethod}" oncomplete="dialog.show()">
Regarding the oncomplete="dialog.show()" - I'm not entirely sure if you need that. A precise answer can be given if you provide more code regarding your table and code.

I had the same problem, and solution is to update a form instead of dialog. For example:
<p:dialog id="id_dialog" ...>
<h:form id="id_form">
... content
</h>
</p:dialog>
and commandLink:
<p:commandLink update=":id_form" process="#all" ...>
This worked for me!

Related

jsf different between ajax=true and ajax=false

I have a JSF page. The framework is PrimeFaces.
The layers build up like topbar, sidebar, main-layout.
The sidebar and top bar contain a menu. Both menus are in a <form>:
<p:commandLink action="#{bean.modify}" ajax="false">
<span>Modify</span>
</p:commandLink>
The main layout also contains buttons form in another form tThe button contains a confirmDialog):
<p:commandLink id="close" action="#{bean.close}" ajax="false" update="form">
<span>Close</span>
<p:confirm header="Lezárás" message="Are you sure close it?" icon="ui-icon-alert"/>
</p:commandLink>
If I use ajax=true, just by clicking on the button in the main layout, confirmDialog does not appear.
If I use ajax = false, confirmationDialog will appear, but the page will break down for a short time. First, the page will be displayed without css formatting, and later the css will be validated.
Why can this be? What's the difference between the seven calls? In one case, why does this render the rendering in the other case why the confirmDialogs do not come up?
Update:
I've read the link, but I still do not understand why it works.
I may have written the problem incorrectly.
There is a JSF page: list.xhtml. It is a commandLink
<p:commandLink action="#{bean.modify}" ajax="false">
<span>Modify</span>
</p:commandLink>
The backing bean:
public String modify(){
return "edit.xhtml";
}
The edit.xhtml has the button with confirmDialog:
<p:commandLink id="close" action="#{bean.close}" ajax="false" update="form">
<span>Close</span>
<p:confirm header="Lezárás" message="Are you sure close it?" icon="ui-icon-alert"/>
</p:commandLink>
If I call edit.html with list.xhtm with ajax = true then confirmDialog works but the page is rendering slowly.
If I call ajax = false then rendering is fast but confirmationDialog does not work.
I do not understand because it is another page, so not just part of it is updated but the entire page
Solved
There was a bug in PrimeFaces.
https://github.com/primefaces/primefaces/commit/9f86efba16ead70f9db1194744d291a7f64acefb
I've corrected the bug in source code version 6.2 and has been working well since then.

Primefaces process attribute in reseting form inputs

I have a form inside a modal dialog and after closing (hiding in fact) one I wanted to reset all inputs that user might have changed. I though about something like as follow:
<p:dialog widgetVar="myDialog">
<h:form id="formId">
<!-- ... -->
<p:commandButton value="Cancel" onclick="myDialog.hide();"
update="formId">
<p:resetInput target="formId" />
</p:commandButton>
</h:form>
</p:dialog>
But the result was not that I expected. After a while of searching I found a solution that was to add process="#this" attribute to the <p:commandButton>. And my question is why it is necessary? What is really happening in backgroud that this process is desired. I don't really get the idea of process attribute at all.
I have done some work with dialog boxes and the way I did to make the form null is, when clicking the button to open dialog box, I ran a method in backing bean which cleared my pojo so my form had empty values.
In your case it could be something like this:
<h:form id="form-button">
<p:commandButton id="AddButton" value="open dialog box"
update=":form" action="#{myBean.myMethodToSetPojoNull}" immediate="true"
oncomplete="PF('myDialog').show()" />
</h:form>
When clicking this button, the called method will set to null all the fields and your dialog box will be empty. Getting back to your question of why process=#this is neccessary much better explained answer is here
What is the function of #this exactly?
You can also reset input after submitting through this method:
<p:commandButton value="Reset Non-Ajax"
actionListener="#{pprBean.reset}" immediate="true" ajax="false">
<p:resetInput target="panel" />
</p:commandButton>
If you don't add process="#this" then by default attribute value will be set to process="#form" which means all the elements in the form are processed. In command buttons process="#this" is mandatory to execute the corresponding actions associated with that button.
You can directly refer the answer from Balusc in this link
What is the function of #this exactly?

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 panelgrid update from datatable

I am getting "Cannot find component with identifier "contentForm:tabView:form:addressDialogPanel" referenced from "contentForm:tabView:form:addressBookTable" " error. How can I update my panelGrid inside the widget?
<h:form id="form">
<p:dataTable id="addressBookTable">
<p:ajax event="rowSelect" listener="#{addressBookController.onRowSelect}"
update="contentForm:tabView:form:addressDialogPanel" oncomplete="addressDialog.show()" />
</p:dataTable>
<p:dialog id="addressDialogId" widgetVar="addressDialog">
<h:panelGrid id="addressDialogPanel" columns="2" cellpadding="4">
</h:panelGrid>
</p:dialog>
</h:form>
The main problem is that you are giving the wrong client ID of component's. Also p:tabView is a component it is not a form. When you define a h:form, it generates a standart HTML form element. And when you submit the page JSF uses POST to submit your data into backing bean. So nesting them is going to occur lot's of issues that you don't expect. You should seperate forms into sections like sideForm or searchForm or etc.
You should detect the correct client ID of your component when you try to update it. You can do this with your browser's developer settings(press f12 for chrome). Then select component with the magnifier button and give that ID into update property. Just like here:
You should read to learn basics of JSF for example from here

Setting bean property before opening Primefaces dialog

I would like to achieve this functionality.
<p:column>
<p:commandLink value="prihlasit" oncomplete="dlg.show();"
action="#{signForProjectBean.setProjectForDetail(item)}" />
</p:column>
I think is pretty clear what I am trying to do, I would like to display detail of the row in dataTable on which user have clicked. So my approach is to set property of current row to bean and then show the detail in dialog. But it is not working and I am feeling that I am doing something really wrong:-)
If the dialog component is supposed to display the selected item, then you need to ajax-udpate the dialog's content before opening it. Otherwise it will still display the old content as it was when the page is rendered for the first time.
<p:commandLink value="prihlasit" update=":dlg" oncomplete="dlg.show();"
action="#{signForProjectBean.setProjectForDetail(item)}" />
...
<p:dialog id="dlg" ...>

Resources