Simple pop-up after p:selectBooleanCheckbox? - jsf

I have several pages where I am using PrimeFaces checkbox in this way:
<p:column>
<f:facet name="header">
<p:selectBooleanCheckbox value="#{Bean.allChecked}">
<p:ajax process="#this" update=":form:table" listener="#{Bean.handleAllChecked}"/>
</p:selectBooleanCheckbox>
</f:facet>
...
</p:column>
I'd like to bring up an info pop-up dialog saying "This will select all items!" with only one "OK" button. How would I do that?
Have in mind that there are several pages with the same behaviour, and I'd like to avoid copy/pasting the same code over and over again if possible.

This can be achived by using primefaces commandButton and Confirmation dialog
in your xhtml file
<f:facet name="header">
<p:commandButton value="Select All" actionListener="#{testBean.handleAll}">
<p:confirm header="Select All" message="This will select all items?"
icon="ui-icon-alert" />
</p:commandButton>
</f:facet>
Add confirmation dialog code (you can create one file and just include in any xhtml )
<p:confirmDialog global="true" showEffect="fade" hideEffect="explode">
<p:commandButton value="Yes" type="button"
styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
<p:commandButton value="No" type="button"
styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
</p:confirmDialog>
Managedbean
public void handleAll(ActionEvent event){
System.out.println("called only when selected yes");
}
The method handleAll will only be called if user clicks "Yes" otherwise it won't do anything.
I hope that help

Related

Keep p:dialog open when validation failed

I have a simple page with data table. Above the table theres a button to add a new table row. This button opens up a pop up form with the registration form. The object which is being created in that form has a bean validation set. Now when I submit an invalid form, the data is not added, a message is created and the pop up window is closed.
My problem is that I want to keep the pop up window open in case the validation is not passed.
The pop up window code:
<p:dialog header="New company registration" widgetVar="cmpRegDialog" modal="true" showEffect="fade" hideEffect="fade" resizable="false">
<p:outputPanel id="cmpRegistration" style="text-align:center;">
<h:panelGrid id="cmpRegistrationGrid" columns="3" columnClasses="label,value" cellpadding="5">
<p:outputLabel for="cmpNameR" value="Name:"/>
<p:inputText id="cmpNameR" value="#{companyBean.newCompany.name}" />
<p:message for="cmpNameR" />
<p:outputLabel for="cmpAddressR" value="Address:"/>
<p:inputText id="cmpAddressR" value="#{companyBean.newCompany.address}" />
<p:message for="cmpAddressR" />
<p:outputLabel for="cmpIcoR" value="ICO:"/>
<p:inputText id="cmpIcoR" value="#{companyBean.newCompany.ico}" />
<p:message for="cmpIcoR" />
<p:commandButton value="Submit" styleClass="secondary-btn flat" action="#{companyBean.registerNewCompany()}" update=":companyRegistrationForm :companiesOverviewForm"/>
<p:commandButton value="Reset" update="cmpRegistrationGrid" process="#this" style="margin-right:10px; width: auto;" styleClass="indigo-btn" >
<p:resetInput target="cmpRegistrationGrid" />
</p:commandButton>
</h:panelGrid>
</p:outputPanel>
</p:dialog>
Yep just add this to your "Submit" button oncomplete="if (!args.validationFailed) PF('#cmpRegDialog').hide();"
<p:commandButton value="Submit"
styleClass="secondary-btn flat"
action="#{companyBean.registerNewCompany()}"
update=":cmpRegistration :companiesOverviewForm"/>
oncomplete="if (!args.validationFailed) PF('#cmpRegDialog').hide();"
Basically only close the dialog if there was no validation failure. NOTE: Make sure not to update="" the form enclosing the dialog or else your dialog will close every time. You should only update the panel inside the dialog "cmpRegistration" like I have done above.

Primefaces datatable update datatable

I have a problem with primefaces datatables. I have one datatable with some entries and a column with a button inside. If the button is pressed a popup is opened with another datatable. The entries in the second datatable are depending on the row in which the button is pressed.
<!-- first datatable -->
<h:form id="list">
<p:dataTable id="list1" var="item" value="#{bean1.itemlist}"
rowKey="#{item.id}" selection="#{bean1.selectedItem}"
selectionMode="single">
<p:column headerText="ID">
<h:outputText value="#{item.id}" />
</p:column>
...
<p:column headerText="Edit Entries">
<p:commandButton value="Edit Entries"
actionListener="#{bean2.updateEntries(item)}" ajax="true"
oncomplete="PF('edit_entries').show()" />
</p:column>
</p:dataTable>
<!-- Second datatable in the popup -->
<p:dialog header="Edit Entries" widgetVar="edit_entries" modal="true"
resizable="false">
<p:dataTable id="list2" var="entry"
value="#{bean2.entriesList}" rowKey="#{entry.id}"
selection="#{bean2.selectedEntry}" selectionMode="single">
<p:column headerText="Entry Number">
<h:outputText value="#{entry.number}" />
</p:column>
</p:dataTable>
<f:facet name="footer">
<p:commandButton value="Save" oncomplete="PF('edit_entries').hide()" />
</f:facet>
</p:dialog>
</form>
Bean2
public void updateEntries(Item selectedItem) {
this.entriesList = this.entriesQuery.getAllEntriesByItemID(selectedItem.getId());//db query could take some time
System.out.println("entrieslist size: " + this.entriesList.size()); //prints the correct size
}
The problem is that there are no entries listed in the popup datatable although there are some in the list after the db query.
Any ideas how to fix this bug?
Thanks in advance!
UPDATE 1:
<!-- first datatable -->
<h:form id="list">
<p:dataTable id="list1" var="item" value="#{bean1.itemlist}"
rowKey="#{item.id}" selection="#{bean1.selectedItem}"
selectionMode="single">
<p:column headerText="ID">
<h:outputText value="#{item.id}" />
</p:column>
...
<p:column headerText="Edit Entries">
<p:commandButton value="Edit Entries" update=":dialogUpdateEntries"
actionListener="#{bean2.updateEntries(item)}" ajax="true"
oncomplete="PF('edit_entries').show()" />
</p:column>
</p:dataTable>
</h:form>
<!-- Second datatable in the popup -->
<p:dialog header="Edit Enries" id="dialogUpdateEntries" widgetVar="edit_entries" modal="true"
resizable="false">
<h:form id="formEntriesList">
<p:dataTable id="list2" var="entry"
value="#{bean2.entriesList}" rowKey="#{entry.id}"
selection="#{bean2.selectedEntry}" selectionMode="single">
<p:column headerText="Entry Number">
<h:outputText value="#{entry.number}" />
</p:column>
</p:dataTable>
<f:facet name="footer">
<p:commandButton value="Save" oncomplete="PF('edit_entries').hide()" />
</f:facet>
</form>
</p:dialog>
You're indeed not updating the data table in the dialog. JSF doesn't automatically update the view on change of the model, you have to explicitly tell the view to do so. You can use the ajax action component's update attribute for this. This takes a JSF client ID which can be found by rules as outlined in this related answer: How to find out client ID of component for ajax update/render? Cannot find component with expression "foo" referenced from "bar".
Given the markup as shown in the question, that'll be
<p:commandButton ... update=":list:list2" />
However, there's another potential problem. You're using <p:dialog modal="true"> inside a form instead of giving the dialog its own form. This way the dialog may not be available in the HTML DOM tree as JavaScript (the one responsible for dealing with ajax stuff) would expect to find it. Giving the dialog its own form should fix this matter. It'll also fix the potential future problems with invoking actions from inside the dialog as handled in this related question: <p:commandbutton> action doesn't work inside <p:dialog>.
<h:form id="viewForm">
...
<p:commandButton ... update=":editDialog" />
...
</h:form>
<p:dialog id="editDialog" modal="true">
<h:form id="editForm">
...
</h:form>
</p:dialog>
Try adding update="list2" to Edit Entries command button (even update="#widgetVar(edit_entries)" should work).
If, because of page layout and structure, you can't target the second datatable using above suggestions, then add styleClass="tList2" to second table, and update it with update="#(.tList2)" on edit button.

PrimeFaces Composite Components: commandLink doesn't work in dataTable

'
<cc:implementation>
<p:outputLabel value="#{cc}"/>
<p> <p:commandButton value="Vedi lista file" actionListener="#{cc.researchFileInDirectory}" update="panelFileLog"/></p>
<h:panelGrid id="panelFileLog">
<p:dataTable var="file" rendered="#{cc.viewFileList}" binding="#{cc.listaFile}">
<p:column headerText="File" style="width:100px">
<h:outputText value="#{file.toString()}" />
</p:column>
<p:column headerText="Link" style="width:100px">
<p:commandLink id="downloadLink" value="download" ajax="false" actionListener="cc.downloadFile">
<p:fileDownload value="#{cc.file}" />
</p:commandLink>
</p:column>
</p:dataTable>
</h:panelGrid>
</cc:implementation>'
This component is called in this page
<l:logFile />
It loads the list of files but when I click on commandLink, it does not call the actionListener method but redirects me to the same page.
Every component that uses StreamedContent does not work in a composite component. For more detailed explained, please read http://jsfcorner.blogspot.be/2012/11/advanced-primefaces-graphic-image.html . Since <p:fileDownload/> is one of them you can't use it.

Primefaces Confirm Message Updated Value

I'm trying to show an updated value in confirm dialog message but I keep getting the old value as in this scenario
<h:form>
<p:inputText value="#{bean.object.amount}"/>
<p:commandButton value="CALCULATE" update="cal" actionListener="#{bean.calculate()}"/>
<h:panelGroup id="cal">
<h:outputText value="#{bean.object.amount}"/>
<p:commandButton value="SUBMIT" actionListener="#{bean.submit()}">
<p:confirm header="Confirmation" message="Amount is : #{bean.object.amount} ?"/>
</p:commandButton>
<p:confirmDialog global="true">
<p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
</p:confirmDialog>
</h:panelgGroup/>
</h:form>
Bean code:
#ManagedBean(name="bean")
#ViewScoped
public class Bean implements Serializable {
private SomeClass object;
#PostConstruct
public void init(){
this.object = new SomeClass();
}
public void calculate(){
//do some colculation (not related to amount field in object)
}
public void submit(){
//submit to database
}
//getter setter
}
When I enter a value in amount, lets say 50. and update the cal component I get the updated amount in the outputtext "50". However, in the confirm button message I get amount as 0 instead 50. How can I show the updated value in the confirm message?
PS:
Primefaces-4.0
Take a look at the user guide of primefaces in the confirm dialog section, in the Non-Global mode the document mentioned:
Message facet is
useful if you need to place custom content instead of simple text.
While in the Global mode, I can't find similar sentences like that, and I've tried using the facet in Global mode and it doesn't work.So,
Do you really use this confirm dialog multiple times?
If not:
I suggest you take away the global parameter and change your code like this:
<h:form>
<p:inputText value="#{bean.object.amount}"/>
<p:commandButton value="CALCULATE" update="cal" actionListener="#{bean.calculate()}"/>
<h:panelGroup id="cal">
<h:outputText value="#{bean.object.amount}"/>
<p:commandButton value="SUBMIT" actionListener="#{bean.submit()}" oncomplete="PF('confirmDlg').show()"/>
<p:confirmDialog header="Confirmation" widgetVar="confirmDlg">
<f:facet name="message">
<h:outputText value='Amount is : #{bean.object.amount} ?'/>
</f:facet>
<p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
</p:confirmDialog>
</h:panelGroup>
</h:form>
.
If so:
(You do use the confirm dialog multiple times and tired of writing several dialogs with same form but different message.)
I suggest you write a dialog on your own,and you can also change the message in the dialog from backing bean like what you did:
<h:form id="myForm">
<p:inputText value="#{bean.object.amount}"/>
<p:commandButton value="CALCULATE" update="cal" actionListener="#{bean.calculate()}"/>
<h:panelGroup id="cal">
<h:outputText value="#{bean.object.amount}"/>
<ui:param name="message" value="Amount is :#{bean.object.amount}?" />
<p:commandButton value="SUBMIT" actionListener="#{bean.setMessage(message)}" action="#{bean.submit()}" update="myForm:myDialog" oncomplete="PF('myDlg').show()"/>
</h:panelGroup>
<p:dialog id='myDialog' widgetVar="myDlg" header="Confirmation" modal="true" resizable="false">
<h:panelGrid columns="3">
<h:panelGroup styleClass="ui-icon ui-icon-alert" style="float:right"/>
<h:outputText value="#{bean.message}"/>
<h:outputText/>
<h:outputText/>
<p:commandButton value="Yes" type="button" icon="ui-icon-check" oncomplete="PF('myDlg').hide()"/>
<p:commandButton value="No" type="button" icon="ui-icon-close" onclick="PF('myDlg').hide()"/>
</h:panelGrid>
</p:dialog>
</h:form>
p:confirm does not implement state saving, thus it loses its attributes' values after the first JSF lifecycle. It also evaluates EL only once at view build time.
I posted the solution in this answer.

Display a formatted text / message on p:confirmDialog

When a row in <p:dataTable> is right-clicked, <p:contextMenu> appears with a delete option. When this option is clicked, <p:confirmDialog> appears with two buttons Yes and No - a conformation warning about deleting the current row as follows.
<p:contextMenu for="dataTable">
<p:menuitem oncomplete="confirmDelete.show()"
value="Delete"
update="confirmDialog"
process="#this dataTable"
actionListener="#{testManagedBean.deleteActionListener}"
icon="ui-icon-close" ajax="true"/>
</p:contextMenu>
<p:confirmDialog id="confirmDialog"
widgetVar="confirmDelete"
message="#{testManagedBean.message}"
header="Message"
severity="alert"
closeOnEscape="true"
showEffect="slide"
hideEffect="fold"
appendTo="#(body)"
closable="true">
<p:commandButton id="btnYes"
value="Yes"
process="#this"
oncomplete="confirmDelete.hide()"
actionListener="#{testManagedBean.deleteActionListener}"
update="dataTable"/>
<p:commandButton id="btnNo"
value="No"
onclick="confirmDelete.hide()"
type="button" />
</p:confirmDialog>
Is there a way to set the message attribute with a formatted message on this dialog.
For example, the property testManagedBean.message in its managed bean is set to a string like
You are about to delete <font color='#ff0000'>2</font> rows. <br/>This action will never be undone. <br/>Are you sure?
The confirm dialog displays this string as a whole. HTML in this string should be interpreted as HTML. I don't see any attribute like escape in <p:confirmDialog>.
Is there a way to display this string as a formatted message.
I found an ugly solution nesting of <f:facet name="message"> within <p:confirmDialog>.
<p:confirmDialog id="confirmDialog"
widgetVar="confirmDelete"
header="Message"
severity="alert"
closeOnEscape="true"
showEffect="slide"
hideEffect="fold"
appendTo="#(body)"
closable="true">
<p:commandButton id="btnYes"
value="Yes"
process="#this"
oncomplete="confirmDelete.hide()"
actionListener="#{testManagedBean.deleteActionListener}"
update="dataTable"/>
<p:commandButton id="btnNo"
value="No"
onclick="confirmDelete.hide()"
type="button" />
<f:facet name="message">
<h:outputFormat value="#{testManagedBean.message}" escape="false"/>
</f:facet>
</p:confirmDialog>
Removing the message attribute from <p:comfirmDialog> and nesting <f:facet name="message"> inside it.
Note : <h:outputFormat> is only needed, if one or more parameters need to be passed by means of nested <f:param> to be substituted in respective placeholders ({0}) in the message text. Just keep on using <h:outputText escape="false">, if no such parameters need to be passed.

Resources