PrimeFaces commandButton to set edit mode and refresh the form - jsf

I am trying to have a button that sets edit mode and refreshes the form, but by clicking the button, nothing happens.
This is my code:
<h:form>
<h:panelGrid columns="2" cellpadding="5">
<p:commandButton type="submit" value="Edit Your Records" icon="ui-icon-edit"
update="#form" rendered="#{!bean.editMode}">
<f:setPropertyActionListener value="true" target="#{bean.editMode}"/>
</p:commandButton>
<p:commandButton type="submit" value="Exit Edit Mode" icon="ui-icon-back"
update="#form" rendered="#{bean.editMode}">
<f:setPropertyActionListener value="false" target="#{bean.editMode}"/>
</p:commandButton>
</h:panelGrid>
<p:dataTable id="table" value="#{bean.table}" var="apartment">
...
</p:dataTable>
</h:form>
Thanks!

I would suggest using
<h:form>
<p:commandButton value="Edit Your Records" update="#form" rendered="#{!bean.editMode}" action="#{bean.toggleEditMode()}" />
<p:commandButton value="Exit Edit Mode" update="#form" rendered="#{bean.editMode}" action="#{bean.toggleEditMode()}" />
<h:outputText value="#{bean.editMode}" />
and
public void toggleEditMode() {
this.editMode = !this.editMode;
}

ok, it seams that the function called in the 'action' attribute needs to return a String.
The following worked:
public String toggleEditMode() {
this.editMode = !this.editMode;
return "#";
}
Thanks!

Related

Create edit form for Primefaces table

I want to create edit form for Primefaces table. I tested this code:
<h:form id="form">
<p:dataTable id="tbl" var="systemuser" value="#{systemusers.systemUsers}"
selectionMode="single" selection="#{systemusers.selectedSystemUser}" rowKey="#{systemuser.username}" lazy="true"
resizableColumns="true"
>
<p:ajax event="rowSelect" listener="#{systemusers.onRowSelect}" update=":form:carDetail" oncomplete="PF('carDialog').show()" />
....................
</p:dataTable>
<p:dialog id="wd" header="System User Details" widgetVar="carDialog" modal="true" showEffect="fade" hideEffect="fade" resizable="true">
<p:outputPanel id="carDetail" style="text-align:center;">
<p:panelGrid columns="2" columnClasses="label,value">
<h:outputLabel for="id" value="ID" />
<p:outputLabel id="id" value="#{systemusers.selectedSystemUser.id}" rendered="#{not systemusers.editable}"/>
<h:inputText value="#{systemusers.selectedSystemUser.id}" rendered="#{systemusers.editable}" />
........
</p:panelGrid>
</p:outputPanel>
<f:facet name="footer">
<p:commandButton value="Edit System User" rendered="#{not systemusers.editable}"
actionListener="#{systemusers.editRecord(false)}">
<f:ajax render=":form:wd" execute=":form:wd"></f:ajax>
</p:commandButton>
<p:commandButton value="Cancel" rendered="#{systemusers.editable}" actionListener="#{systemusers.editRecord(true)}">
<f:ajax render=":form" execute=":form"></f:ajax>
</p:commandButton>
</f:facet>
</p:dialog>
<p:contextMenu for="tbl">
<p:menuitem value="View" update="carDetail" icon="fa fa-search" oncomplete="PF('carDialog').show()"/>
<p:menuitem value="Delete" update="tbl" icon="fa fa-remove" actionListener="#{systemusers.deleteSystemUser}">
<p:confirm header="Confirmation" message="Are you sure?" icon="fa fa-warning" />
</p:menuitem>
</p:contextMenu>
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade">
<p:commandButton value="Yes" type="button" styleClass="ui-confirmdialog-yes" icon="fa fa-check" />
<p:commandButton value="No" type="button" styleClass="ui-confirmdialog-no" icon="fa fa-remove" />
</p:confirmDialog>
</h:form>
Managed bean:
#Named
#RequestScoped
public class Systemusers implements Serializable
{
.......
public void editRecord(boolean editable)
{
SessionFactory factory = HibernateUtils.getSessionFactory();
Session session = factory.getCurrentSession();
try
{
session.getTransaction().begin();
SystemUsersModel obj = new SystemUsersModel();
obj.setId(selectedSystemUser.getId());
..........
session.update(obj);
session.getTransaction().commit();
this.editable = editable;
}
catch (Exception e)
{
e.printStackTrace();
session.getTransaction().rollback();
}
}
......
private boolean editable = false;
public boolean isEditable()
{
return editable;
}
public void setEditable(boolean editable)
{
this.editable = editable;
}
}
When I open the Edit form and I click button Edit System User the form disappears. Probably because I render and execute it. How I can execute the form and under it without closing it?
The example code is bad in multiple ways. Two things stand out:
It is not an [mcve]
<f:ajax render=":form" execute=":form"> is superfluous or might even cause the weird behaviour
OP most likely does not know that (quote from the PrimeFaces showcase , emphasis mine)
CommandButton
CommandButton extends the standard h:commandButton with ajax, partial processing and skinning features.
So the commandBotton is already ajax anabled and does not need to hava a
<f:ajax render=":form" execute=":form">
inside it. This (most likely) makes an the update run twice. One #none (Understanding PrimeFaces process/update and JSF f:ajax execute/render attributes) and one updating the form. The second one most likely does not have any content. But trying (and debugging) will make things clear. If this is not the answer, the reason cannot be seen in the code and hence it should have been a [mcve]

how to reload p:dataGrid programmatically?

I have a datagrid with subscribe and unsubscribe option so the user can subscribe and unsubscribe and vise verse.
now I want to reload the datagrid after subscription or unsubscription
I load the data of the grid like that
#PostConstruct
public void init() {
packages = packagehelper.getAllPackages();
getCurrentUserSubscritions();
}
and here is the xhtml file
<h:form id="form">
<p:growl id="growl" showDetail="true" sticky="false" life="8000" />
<p:dataGrid var="package" value="#{packageView.packages}" columns="3"
>
<p:column>
<f:facet name="header">
Cars for Sale
</f:facet>
<p:panel header="#{package.id}" style="text-align:center">
<h:panelGrid columns="2" style="width:100%">
<p:graphicImage width="100px" name="images/#{package.imageurl}"/>
<h:outputText value="#{package.name}" />
<h:outputText value="#{package.value} EGP for #{package.duration} Days " />
<h:outputText value="#{package.description}" />
<p:commandButton ajax="true" update=":pack" value="Subscribe" rendered="#{!packageView.IsPackageActive(package.id)}" action="#{packageView.Subscribe()}" >
<f:setPropertyActionListener value="#{package.id}" target="#{packageView.packageID}" />
<f:setPropertyActionListener value="#{package.duration}" target="#{packageView.packageDuration}" />
</p:commandButton>
<p:commandButton action="#{packageView.Unsubscribe}" update=":pack" ajax="true" value="Cancel" rendered="#{packageView.UserHasPackage(package.id) and packageView.IsPackageActive(package.id) }">
<f:setPropertyActionListener value="#{package.id}" target="#{packageView.packageID}" />
<f:setPropertyActionListener value="#{package.duration}" target="#{packageView.packageDuration}" />
</p:commandButton>
</h:panelGrid>
</p:panel>
</p:column>
</p:dataGrid>
</h:form>
When an suscribe or unsuscribe action is completed, you should actualize the DataGrid trough its ID, it is, set an ID to the DataGrid and put such id in the update property of the buttons.
For example:
<p:dataGrid id="datalist" .../>
<p:commandButton action="#{packageView.Unsubscribe}" update="datalist" .../>
And when the action of the button is submited set the packages in null, so when the update action of the DataGrid update the packages they should be called again of the persistence or data base.
It is important to consider how to reference the elements in update property. You can see this answer

Datatable link to edit record only works once unless I hit refresh

working with a Primefaces data table and dialog. Each record in data table has a link as such:
<p:commandLink value="#{item.pk}" update=":itemUpdateForm:display"
onclick="PF('itemUpdateDialog').show();" title="Edit">
<f:setPropertyActionListener value="#{item}"
target="#{itemController.selecteditem}" />
</p:commandLink>
The link opens a primefaces dialog successfully the first time but after I submit the form in this popup dialog, which updates that recordset, the links in the datatable will no longer open the dialog again unless I hit refresh on the browser.
Here is the update button in the p:dialog:
<f:facet name="footer">
<p:commandButton value="Update" update=":ItemListForm:dataTable, :growl"
oncomplete=" handleSubmitRequest(xhr, status, args, 'itemDlg','itemUpdateForm');"
actionListener="#{itemController.doUpdateItem()}" />
<p:commandButton type="reset" value="Reset"></p:commandButton>
</f:facet>
And scopes/pertinent code:
itemController
#ManagedBean
#ViewScoped
public class ItemController implements Serializable {
#PostConstruct
public void init() {
items= itemListProducer.getItems();
}
public void doUpdateItem() {
itemRepository.update(selectedItem);
itemEventSrc.fire(selectedItem);
items = itemListProducer.getitems();
Messages.addAjaxMessage("Update Operation Was Successful!");
}
List Producer
#ApplicationScoped
public class ItemListProducer implements Serializable {
Edit
per comment here is DataTable and the Primefaces update dialog
<h:form id="ItemListForm">
<p:dataTable id="dataTable" var="item"
value="#{itemController.items}"
paginator="true" rows="10"
selection="#{itemController.selectedItems}" rowKey="#{item.oc_id}"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
lazy="false" rowsPerPageTemplate="10,15,50">
<f:facet name="header">
Items (#{itemController.items.size()})
</f:facet>
<p:column selectionMode="multiple" style="width:18px"/>
<p:column filterBy="#{item.oc_id}" sortBy="#{item.oc_id}">
<f:facet name="header"><h:outputText value="OC #" /></f:facet>
<p:commandLink value="#{item.pk}" update=":itemUpdateForm:display" onclick="PF('itemUpdateDialog').show();" title="Edit">
<f:setPropertyActionListener value="#{item}" target="#{itemController.selecteditem}" />
</p:commandLink>
</p:column>
more p:columns
<f:facet name="footer">
<p:commandButton value="New item" onclick="PF('dlg1').show();" title="Creates new Item" />
<p:commandButton value="Delete Selected Items"
actionListener="#{itemController.doDeleteItems}"
update="#form, :growl">
<p:confirm header="Confirmation" message="Are you sure you want to remove the selected Items?" />
</p:commandButton>
</f:facet>
</p:dataTable>
<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:form>
... and dialog
<p:dialog header="Item Update Form" widgetVar="itemUpdateDialog" resizable="false" id="itemDlg">
<h:form id="itemUpdateForm">
<p:panel>
<p:panelGrid id="display" columns="3" cellpadding="4"
style="margin:0 auto;">
<h:outputText value="Title :"></h:outputText>
<p:inputText id="title" value="#{itemController.selectedItem.title}"
required="true"
requiredMessage="Please Enter Title!" />
<p:message for="title" />
other inputs
<f:facet name="footer">
<p:commandButton value="Update" update=":ItemListForm:dataTable, :growl"
oncomplete=" handleSubmitRequest(xhr, status, args, 'itemDlg','itemUpdateForm');"
actionListener="#{itemController.doUpdateItem()}" />
<p:commandButton type="reset" value="Reset"></p:commandButton>
</f:facet>
</p:panelGrid>
</p:panel>
</h:form>
</p:dialog>
EDIT 2
Thanks to help from Michele's Answer, I determined the issue was related to how I was closing the dialog by its id and not by its widgetVar. I was originally passing in just the id which was used with jQuery effect 'shake', and then closing that object. By adding the widgetVar and using Michele's var d = (typeof dialogWv === "string") ? PF(dialogWv) : dialogWv; I no longer have my issue.
This ultimately works for me:
<p:dialog header="Update Form" widgetVar="itemUpdateDialogWv"
resizable="false" id="itemUpdateDialogId">
<h:form id="itemUpdateForm">
<p:panel>
------content-------
<f:facet name="footer">
<p:commandButton value="Update" update=":ItemListForm:dataTable, :growl"
oncomplete=" handleSubmitRequest(xhr, status, args, 'itemUpdateDialogWv','itemUpdateForm', 'itemUpdateDialogId');"
actionListener="#{itemController.doUpdateItem()}" />
<p:commandButton type="reset" value="Reset"></p:commandButton>
</f:facet>
</p:panelGrid>
</p:panel>
</h:form>
</p:dialog>
function handleSubmitRequest(xhr, status, args, dialogWv, formName, dialogNameId) {
dialog = jQuery('#'+dialogNameId);
var d = (typeof dialogWv === "string") ? PF(dialogWv) : dialogWv;
if(args.validationFailed) {
dialog.effect("shake", { times:5 }, 1000);
} else {
clearForm(formName);
d.hide();
}
}
function clearForm(formName){
jQuery('#'+formName).each(function(){
this.reset();
});
}
Too long for a comment...
You can try:
<p:commandLink value="#{item.pk}" process="#this" update=":itemUpdateForm"
oncomplete="PF('itemUpdateDialog').show();" title="Edit">
<f:setPropertyActionListener value="#{item}" target="#{itemController.selecteditem}" />
</p:commandLink>
specify process="#this": otherwise it defaults to #all and will include the dialog too
use oncomplete instead of onclick
and
<p:commandButton value="Update" process="#form" update="#form, :ItemListForm, :growl"
oncomplete="handleSubmitRequest(xhr, status, args, 'itemDlg','itemUpdateForm');"
actionListener="#{itemController.doUpdateItem}" />
specify process="#form": the same as before
add #form to update: generally is a good practice to update the dialog form tho show validation errors and to close dialog only if not validation failed (I don't know how handleSubmitRequest works, maybe it does exactly this)
However:
No js errors on commandButton click?
Is request fired?
If yes, can you post request params for the not working click?
P.S.
handleSubmitRequest(xhr, status, args, 'itemDlg','itemUpdateForm'); has argument itemDlg. Is it correct?
for completeness here is my hideDialog
function hideDialog(dialog, args, status, xhr)
{
var d = (typeof dialog === "string") ? PF(dialog) : dialog;
if(!args.validationFailed)
{
d.hide();
}
}
which is invoked:
<p:commandButton value="Update" process="#form" update="#form :ItemListForm :growl"
oncomplete="hideDialog('itemUpdateDialog', args)"
actionListener="#{itemController.doUpdateItem}" />

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.

How to reset dropdown on primefaces commandButton without java script?

I want to reset <p:selectOneMenu> in primeface. I used type="reset" this can reset the text fields only not a selectonemenu. My code
<p:panel id="Applyleave_panel" >
<p:selectOneMenu id="leavetype" value="#{requestbean.leavetype}" required="true" style="width:50%;">
<f:selectItem itemLabel="Select type" itemValue="" />
<f:selectItems value="#{requestbean.leave_type}" />
</p:selectOneMenu>
</panel>
<p:commandButton value="Reset" type="reset"/>
You can use p:resetInput given that your component is inside a form.
<p:commandButton value="Reset" update=":form" immediate="true">
<p:resetInput target=":form" />
</p:commandButton>
EDIT: You can also target the p:panel component as well.
<p:commandButton value="Reset" update=":Applyleave_panel" immediate="true">
<p:resetInput target=":Applyleave_panel" />
</p:commandButton>
I use the below
<p:commandButton id="resetSearchCir" type="reset"
value="#{button.reset}" immediate="true">
<f:ajax event="click"
listener="#{searchBean.resetActionListener}" render="#form" />
</p:commandButton>
public void resetActionListener(AjaxBehaviorEvent event) {
LOG.info("Reset button clicked...");
setResetClicked(true);
// re-initialise your form field objects which you want to reset
logWarn("All values have been reset. Please enter the new values to search again.");
}

Resources