Delete a row in datatable with confirmDialog - jsf-2

My problem consists in deleting an item from data table. When i click on the button delete a confirm Dialog will appear to confirm removing the row from database. If so, the data will be removed but the data table isn't updated unless i logout and login and if i select another item it won't be even deleted.
<h:form id="form">
<p:panel id="panelform" header="Databases" >
<p:dataTable value="#{dataMB.customersDatas}" var="item" id="datas" rowsPerPageTemplate="5,10,15,20,25,30" paginator="true" rows="10" filteredValue="#{dataMB.filteredDatas}" selectionMode="single" rowKey="#{item.id}"selection="#{dataMB.selectedData}">
<p:ajax event="rowSelect" update=":form:dataView, :form:deleteButton, :form:viewButton" listener="#{dataMB.onRowSelect}"/>
</p:dataTable>
<p:panel>
<p:commandButton style="width: 8%;height: 100%" id="viewButton" value="View" oncomplete="dataDialogView.show()" disabled="#{dataMB.disabled}" icon="ui-icon-search" title="data details"/>
<p:commandButton style="width: 8%;height: 100%" id="deleteButton" value="Delete" oncomplete="deleteDialog.show()" disabled="#{dataMB.disabled}" icon="ui-icon-trash"/>
</p:panel>
</p:panel>
</h:form>
<p:confirmDialog style="position: absolute; width: 50px; border-color: blue" id="deleteData" message="Your Database Will be completely removed . Are you sure? " appendToBody="true" header="Delete Data" severity="alert" widgetVar="deleteDialog">
<h:form>
<p:commandButton id="confirm" style="width: 25%;height: 100%" value="Confirm" actionListener="#{dataMB.deleteData()}" update=":form:datas" ajax="true" oncomplete="deleteDialog.hide(); purchase.hide();" >
</p:commandButton>
<p:commandButton id="cancel" style="width: 25%;height: 100%" value="Later" onclick="deleteDialog.hide();" type="button" />
</h:form>
</p:confirmDialog>
deleteData() method in my sessionScoped managed Bean
public String deleteData() {
logger.log(Level.SEVERE, "*****delete Data***** ");
dataBusinessLocal.deleteData(selectedData);
return "datalist";
}

JSF is session based. To synchronize the state between client (browser) and server, JSF uses a hidden field javax.faces.ViewState. Right now, you are using two forms on the given page:
Clicking Action-Button on Form one
confirming on form two with updating the data table of form one
So, the hidden input field viewState isn't accurate any longer. Two ways I would possibly try:
Does the confirm-box have to be fancy JSF or does a javascript solution the job as well?
<p:commandButton id="deleteButton"
value="Delete"
disabled="#{dataMB.disabled}" icon="ui-icon-trash"
actionListener="#{dataMB.deleteData}"
onclick="if (!confirm('really delete?')) { return false;}" />
might do a similar job.
Possibility two: just rerender the whole form or the panel panelform instead of just the data table. This way a new javax.faces.ViewState should be rendered and the form works fine again.
Also, add a <h:messages /> somewhere in and update it on every step. In case there is a unexpected error, this might show it on the UI.
Hope that helps...

Related

Primefaces dialog client validation not displaying

I have a Primefaces 5.0 modal dialog on a composite control. The dialog has a few field marked as required. When the button on the dialog is clicked I expected the client validation to fire and it seems it does as the backing bean is not called, but the messages are not displaying:
<p:dialog id="dialogCorporateShareHolder" header="Shareholder (Company)"
widgetVar="dlgCorporateShareHolder" modal="true">
<p:panelGrid columns="3" id="corporateShareHolderDetails">
<h:outputLabel for="companyName" value="Company name"/>
<p:inputText id="companyName" required="true"
value="#{cc.attrs.corporateShareHolder.companyName}"
label="Company name"/>
<p:message for="companyName"/>
<f:facet name="footer">
<p:commandButton id="submitCorporate" value="Submit"
update="corporateShareholders"
actionListener="#{cc.attrs.controller.addCorporateShareHolder}"/>
</f:facet>
</p:panelGrid>
</p:dialog>
The dialog displays, the validation gets called (I'm pretty sure), but no message is displayed.
You only need to update the p:message or a parent too, for example with
update="corporateShareholders corporateShareholderDetails"
Btw. I believe best practises are to
have the dialog(s) last in xhtml, outside of other forms
have a form inside the dialog itself

Opening one <p:confirmDialog> from another <p:confirmDialog> in JSF

I have a JSF page in which I have two dialogs. I want to open one dialog on closing the other.I am using Primefaces 4.0.
Here is my JSF page.
<h:form>
<h:commandLink value="Click me" onclick="bezoekConfirmation.show();return false;"/>
<p:confirmDialog
message="Bent u zeker dat u dit bezoek wilt verwijderen?"
closable="false" header="Bezoek verwijderen" severity="alert"
widgetVar="bezoekConfirmation">
<p:commandButton value="Yes" oncomplete="bezoekConfirmation.hide()"
onclick="dialog.show();" ajax="false" />
<p:commandButton value="No" onclick="bezoekConfirmation.hide()"
type="button" />
</p:confirmDialog>
<p:confirmDialog message="Hai" closable="false"
header="Bezoek verwijderen" severity="alert" widgetVar="dialog">
<p:commandButton value="Yes" oncomplete="dialog.hide()"
action="#{controller.method()}" ajax="false" />
<p:commandButton value="No" onclick="dialog.hide()" type="button" />
</p:confirmDialog>
</h:form>
The first dialog appears. But on clicking the yes button of the first dialog, the second dialog never appears.
However the logic requires both the dialogs to appear one after the other.
Am I missing something?
Remove ajax="false" from the command Button and it will works

ignoreValidationFailed doesn´t work inside ui:repeat

I´m using o:ignoreValidationFailed, but it doesn´t work inside the ui:repeat. When I do the same outside, it works! I tried with mojarra ans MyFaces... I´m using primefaces. If there is another way to skip the validations only for one button...
<o:form id="rateplanEditByPeriod" prependId="false">
<p><p:messages id="mensagensDlg"/></p>
<p:tabView id="tabs">
<p:tab title="Cancelamento" id="tabCanc">
<h:panelGrid id="cancelationsTable" columns="2" cellpadding="10px" columnClasses="alignTop,alignTop">
<ui:repeat id="repeat" var="rest" value="#{rateplanByPeriodManaged.rateplanByPeriod.restriction.restTypeCancelation.restTypeCanConfs}" >
<h:panelGrid columns="8">
<p:inputText id="penaltyValue_#{loop.index}" value="#{rest.penalityValue}" style="width:28px" label="Valor" title="Valor" disabled="#{rest.noCancel}" required="true"/>
<p:commandLink id="add_#{loop.index}" actionListener="#{rateplanByPeriodManaged.addCancConf}" update=":rateplanEditByPeriod:tabs:cancelationsTable" partialSubmit="true" process=":rateplanEditByPeriod:tabs:cancelationsTable" value="+">
<o:ignoreValidationFailed />
</p:commandLink>
<p:commandLink actionListener="#{rateplanByPeriodManaged.removeCancConf(rest)}" value="-" update=":rateplanEditByPeriod:tabs:cancelationsTable" partialSubmit="true" process=":rateplanEditByPeriod:tabs:cancelationsTable">
<o:ignoreValidationFailed />
</p:commandLink>
</h:panelGrid>
</ui:repeat>
</h:panelGrid>
</p:tab>
</p:tabView>
<p:commandLink styleClass="button" onclick="dlgEdit.hide()" immediate="true" update=":msgsPanel">#{msgs['inventory.editByPeriod.cancel']}</p:commandLink>
<p:commandLink styleClass="button" actionListener="#{rateplanByPeriodManaged.editByPeriod(loginManaged.hotelSelected)}" oncomplete="if (!args.validationFailed) {dlgEdit.hide(); updateAllSearches(); updateAllNotifications();}" update="mensagensDlg, tabs" >#{msgs['inventory.editByPeriod.confirm']}</p:commandLink>
</o:form>
I have faced the same issue but with p:datatable
I solved it with
1- add a condition to the required field to know if the ajax come from submit button or not
as #Camilla said.
required="#{!empty param['trans_desc_form:savetransid']}"/>
trans_desc_form is the entire form id and savetransid is the submit button save id
2- I removed #NotNull from my JPA entity which force the validation
#JoinColumn(name = "ITEMNO", referencedColumnName = "ITEMNO")
#ManyToOne(optional = false, fetch = FetchType.LAZY)
//#NotNull
private Item item;
I have created a question for this issue
ignoreValidationFailed doesn´t work inside p:dataTable
I don´t know if it´s the best aproach but it worked for me...
<h: inputText id="text1" value="" required="#{!empty param['formName:btnSave']}" />
This is not the right way to have a "Cancel" button.
Just put process="#this" in the <p:commandLink>, or if you don't need to do any business logic, make it a normal <h:link> which reloads the page (and thus implicitly recreates the request/view scoped bean).
As to <o:ignoreValidationFailed> the failure in <ui:repeat> on its own, please create an issue.

I can't update from within a facet

I'm using primefaces 3.3 with JSF 2.1. In the code below, I have a primeFaces dataTable that contains rows of data drawn from the database which is correctly activated from a tree component on the left part of my page. The dataTable displays and behaves correctly. I have a delete functionality that calls "update" which refreshes my dataTable and reflects my changes after the database was updated. My problem is with with f:facet (id="header"). Contained in that facet is a commandLink that creates a new row in my dataTable. It works in the sense that my database is correctly updated. The dataTable is not refreshed after this. In order to refresh my dataTable, I have to click on another node in my tree component (on the left of the page) and then return to the original treeNode to see my dataTable perfectly updated. What can I add to my code to update the dataTable dynamically?
Unfortunately, I can't add all my permutations that I've tried here - I've spent a long time on this problem - and your inputs will be greatly appreciated!
<h:form id="formRight" >
<p:dataTable var="material" value="#{entityCrudTreeBean.materialList}" id="materials" editable="true" paginator="true" rows="10" sortBy="#{material.name}">
<p:ajax event="rowEdit" listener="#{entityCrudTreeBean.onEditRow}"/>
<f:facet id="header" name="header">
In-Cell Material Editing
<br />
<p:commandLink id="create" value="Add new material" action="#{entityCrudTreeBean.createNewMaterial}" update=":formRight"/>
</f:facet>
<p:column headerText="Name" style="width:125px">
<p:cellEditor>
...
</p:cellEditor>
</p:column>
<p:column headerText="Options" style="width:10px" >
<p:rowEditor />
<p:commandLink id="delete" action="#{entityCrudTreeBean.deleteRow(material)}" update=":formRight">
<h:graphicImage value="#{resource['icons:Delete-icon.png']}" />
</p:commandLink>
</p:column>
</p:dataTable>
</h:form>
edit:
changing the line to
<p:commandLink id="create" value="Add new material" action="#{entityCrudTreeBean.createNewMaterial}" update=":formRight:materials"/>
doesn't work either
edit:
changing to :
<f:facet id="header" name="header">
In-Cell Material Editing
<br />
<p:commandLink id="create" value="Add new material" ajax="true" process="#this" action="#{entityCrudTreeBean.createNewMaterial}" update="#form"/>
</f:facet>
doesn't solve the problem either.
I had a similar issue as you a while back.
My working code looks like:
<f:facet name="header">Product List
<p:commandLink id="create" value="Add new product" ajax="true" process="#this"
action="#{modelBean.save}" update="#form"/>
</f:facet>
Stephen, you're on the right track!
It was solved in a simpler way: I updated my dataTable list in managed bean - which I did for the delete but not for the insert. Massive oversight there.
This code works:
<p:commandLink id="create" value="Add new material" action="#{entityCrudTreeBean.createNewMaterial}" update=":formRight"/>
Tip for people after me: Primefaces 3.3 has a known issue concerning updating within the dataTable. You need to wrap the dataTable with another component like a layout of a form. Calling update on the wrapper works.
According to the primefaces blog from Aug 15, this has been fixed in 3.4.RC1. But they changed the tree components. I'll wait for the 3.4 final release before upgrading.

How to get an ajax event to fire from within a p:dialog

So I have been stumped most of the day today trying to call a method in my backing bean when a component changes values. Everything works correctly if my components are outside of a <p:dialog>, however when nested inside a dialog the server side never happens. Originally I was working with the <p:calendar> control, but noticed it also didn't work with a simple inputText. The following example works:
<h:panelGrid columns="3">
<h:outputText value="Start"/>
<p:inputText id="startOfRange" value="#{myBean.startRange}" valueChangeListener="#{myBean.startChanged}">
<p:ajax event="change" update="play"/>
</p:inputText>
<h:outputText id="play" style="margin-left: 10px;" value="#{myBean.startRange}"/>
</h:panelGrid>
My backing bean method looks like
public void startChanged(ValueChangeEvent event) { }
This method is invoked after a tab out of the inputText, however when wrapped like the following the method never gets invoked:
<p:dialog widgetVar="efDlg" zindex="10" appendToBody="true" header="Create Custom Date Range"
modal="true" height="375" width="450" resizable="false" closable="false" >
<h:panelGrid columns="4">
<h:outputText value="Start"/>
<p:inputText id="startOfRange" value="#{myBean.startRange}" valueChangeListener="#{myBean.startChanged}">
<p:ajax event="change" update="play"/>
</p:inputText>
<h:outputText id="play" style="margin-left: 10px;" value="#{myBean.startRange}"/>
<p:inputText id="endOfRange" value="#{myBean.endRange}" valueChangeListener="#{myBean.endChanged}"/>
</h:panelGrid>
<div class="customRangeButtons">
<span>
<p:commandButton value="Cancel" onstart="efDlg.hide();" actionListener="#{myBean.cancelCustomDateRange}" update="pGraphs"/>
</span>
<span style="margin-left: 300px;">
<p:commandButton value="Ok" type="submit" onstart="efDlg.hide();" action="#{myBean.saveCustomDateRange()}" update="pGraphs"/>
</span>
</div>
</p:dialog>
Note I am using Primefaces 2.2.1 with Mojarra 2.1.0. Any ideas as to why I can't get the startChanged method to be called when the value has changed?
Maybe I'm wrong about this (I don't have my project code at home to verify) but isn't this:
<p:ajax event="change" update="play"/>
supposed to be:
<p:ajax event="valueChange" update="play"/>
I know that most of the Ajax event values are like the JavaScript event handlers with the 'on' removed, but valueChange is a special value in JSF Ajax tags.
For the record, I sometimes pair up two Ajax child tags inside an inputText, like:
<p:ajax event="valueChange" process="#this" update="whatever"/>
<p:ajax event="keyUp" process="#this" update="whatever"/>
This will deal with each keystroke at it is entered as well as copy-and-paste and loss of focus on the parent input text.
I have also come across the same problem. I am also using a single form and no form inside the dialog. As long as I do not have the appendToBody="true" for my dialog the input values and ajax and submit happens correctly. As soon as I add that attribute with true, for better/correct rendering, the input values are not accepted.

Resources