I'm looking for ways to update p:dataTable after running delete method. In my case a user is expected to fill p:dataTable first with a parametrized search. Table contains rows that can be cancelled using delete method. This doesn't mean that they are deleted completely, delete method rather just changes some columns in db table. For example changes hasCancellationReference column to true. Now this means that I need the table still be shown on dataTable row, just with a changed status. Now I'm looking for the correct way to implement dataTable refresh after delete method.
My dataTable and delete button:
<h:form prependId="false" rendered="#{myController.lst ne null and myController.lst.size() gt 0}" id="dataTable">
<p:dataTable value="#{myController.lzy}" lazy="true" var="tra" rows="10" paginator="true" id="dtas"
selectionMode="single" selection="#{myController.cur}" rowKey="#{tra.transactionId}"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {NextPageLink} {LastPageLink}"
paginatorPosition="top"
rowsPerPageTemplate="10,25,50">
<p:ajax event="rowSelect" listener="#{myController.receipt}" update="#{parent}:tradlg" process="#this" global="false" oncomplete="PF('tradlg').show()"/>
<p:ajax event="page" update=""/>
<p:column headerText="Timestamp" width="30">
<h:outputText value="#{path.toGet.myTimeVariable}">
<f:convertDateTime pattern="dd.MM.yyyy HH:mm:ss" timeZone="EET"/>
</h:outputText>
</p:column>
<p:column headerText="Line" width="10">
<h:outputText value="#{var.lineCode}"/>
</p:column>
<p:column headerText="Stop" width="60">
<h:outputText value="#{var.stopCode} #{var.stopName}" />
</p:column>
<p:column headerText="Vechicle" width="30">
<h:outputText value="#{var.vehicleNumber}"/>
</p:column>
<p:column headerText="Status" width="40">
<h:outputText value="Deleted" style="color: red" rendered="#{var.hasCancellationReference eq true}"/>
<p:commandButton value="Delete"
action="#{emvController.deleteTransaction(tra.transitAccount, tra.transactionId)}"
rendered="#{tra.hasCancellationReference eq false}"/>
</p:column>
</p:dataTable>
</h:form>
Things i have tried:
Running search method inside delete method in backend code:
public void deleteRow(int var, String varId) {
try {
MyParameterClass.getInstance().deleteRow(var, varId);
message = MyParameterClass.getInstance().getMessage();
if (message.equals("success 200")) {
successMsg();
//If delete was succesfull run searchMethod
searchMethod();
} else {
errorMsg();
System.out.println("Faces Message Controller: " + message);
}
} catch (Exception ex) {
Logger.getLogger(EmvController.class).error(ex);
return;
}
}
Doing plain refresh on page after delete method. This does work, but i suspect will cause problems with new features I plan to implement in the future.
Related
I'm using:
Server: Wildfly 8.2
JSF: 2.2
Primefaces: 5.2
JDK:8
I have a datatable with multiple selection. I use rowSelectMode='add' so clicking on different rows without modifier keys adds new rows instead of unselecting all selected ones.
<p:dataTable id="table"
value="#{ixController.files}"
var="item" paginatorTemplate="{FirstPageLink} {PreviousPageLink}
{PageLinks}
{NextPageLink} {LastPageLink}"
selection="#{ixController.selecteds}"
rowKey="#{item.id}"
rowSelectMode="add"
selectionMode="multiple">
<p:column headerText="Files">
#{item.fileName}
</p:column>
As stated it works fine for adding rows, however I need to press Ctrl to unselect rows, and the customers wish to just click again on the row and unselect it.
Is that possible somehow?
Use check box instead that way they can select and un-select just by clicking it, follow Prime Faces example:
<p:dataTable id="checkboxDT" var="car" value="#{dtSelectionView.cars6}" selection="#{dtSelectionView.selectedCars}" rowKey="#{car.id}" style="margin-bottom:0">
<f:facet name="header">
Checkbox
</f:facet>
<p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Brand">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
<f:facet name="footer">
<p:commandButton process="checkboxDT" update=":form:multiCarDetail" icon="ui-icon-search" value="View" oncomplete="PF('multiCarDialog').show()" />
</f:facet>
</p:dataTable>
I cant find an attiribute for this, however, there is a way:
<p:dataTable value="#{groupBean.groups}" var="grp" rowKey="#{grp.id}"
selectionMode="single" selection="#{groupBean.group}">
<p:ajax event="rowSelect" listener="#{groupBean.onRowSelect}" update="#all" />
As you see, when a row clicked, selectedItem setted to groupBen.goup object.
public void onRowSelect(SelectEvent event) {
if (prevGroupId == group.getId())
group = new PersonelGroup();
else
prevGroupId = group.getId();
}
In onRowSelect method, you can check if user click same row for the second time by comparing previous selected item id. And by instanciating group object to new, DataTable has been updated to no selection state.
It is important to not forget to add update="#all" attiribute of DataTable.
Im trying to create a select all button or check box that when clicked all the selectbooleanCheck boxes will be checked. is there no straight forward easy way.ive started creating the selectcheckbox that will when changed selectAll. thanks
<p:dataTable value="#{illRequestModel.list}"
var="illRequestRecord" width="100%" styleClass="request-table"
rows="10" paginator="true" id="requestGrid"
currentPageReportTemplate="Viewing Page {currentPage}"
paginatorTemplate="{CurrentPageReport} {PageLinks} "
paginatorPosition="bottom">
<p:column >
<f:facet name="header">
<h:selectBooleanCheckbox id="checkbox2" title="emailUpdates2" onchange="CheckAll()" >
</h:selectBooleanCheckbox>
</f:facet>
<h:selectBooleanCheckbox id="checkbox" title="emailUpdates"
value="#{illRequestRecord.selected}"
onchange="addNumber(#{illRequestRecord.localRequestId})">
<f:ajax listener="#{illRequestRecord.selectmethod}" />
</h:selectBooleanCheckbox>
</p:column>
<p:column id="localRequestIdCol"
sortBy="#{illRequestRecord.localRequestId}">
<f:facet name="header">
<h:outputText value="ID" />
</f:facet>
<h:commandLink value="#{illRequestRecord.localRequestId}"
action="#{requestListController.displaySingleRecord}">
<f:param name="selectedItemId"
value="#{illRequestRecord.localRequestId}"></f:param>
</h:commandLink>
</p:column>
Why don't you use the same multi-selection datatable used in the PrimeFaces DataTable showcase
As you can see in:
<p:dataTable id="multiCars" var="car" value="#{tableBean.mediumCarsModel}" paginator="true" rows="10" selection="#{tableBean.selectedCars}">
It will automatically add a check-all functionality.
In case you want an external checkbox to check all, you can do the following.
Give a widgetVar to you datatable, let's call it dataTableWV
<p:dataTable widgetVar="dataTableWV" id="multiCars" var="car" value="#{tableBean.mediumCarsModel}" paginator="true" rows="10" selection="#{tableBean.selectedCars}">
And you have a checkbox:
<input id="checkAll" type="checkbox" />
You can register a click event on it like the next:
<script>
$(document).ready(function() {
$('#checkAll').on('click', function() {
//selects all records on the displayed page if pagination is supported.
dataTableWV.selectAllRowsOnPage();
//or you can select all the rows across all pages.
dataTableWV.selectAllRows();
});
});
</script>
<p:dataTable widgetVar="dataTableWV" id="multiCars" var="car" value="#{tableBean.mediumCarsModel}" paginator="true" rows="10" selection="#{tableBean.selectedCars}">
<f:facet name="header">
<p:commandButton value="select" onclick="PF('dataTableWV').selectAllRows()" />
<p:commandButton value="unselect" onclick="PF('dataTableWV').unselectAllRows()" />
</f:facet>
</p:dataTable>
Sample Code:-
**JAVA (your backing bean class)
==============================**
//Stores the checked items from data table.
private List<String> selectedIds = new ArrayList<>();
private List<String> getSomeList() {
// return list of strings to data table
return someList;
}
public void selectAllCheckboxes(ToggleSelectEvent event) {
if (selectedIds != null) {
selectedIds.clear();
if (event.isSelected()) {
selectedIds.addAll(someList); //Add all the elements from getSomeList()
}
}
}
**XHTML
=====**
<p:dataTable id="data-table-id" value="#{backingBean.someList}"
selection="#{backingBean.selectedIds}" rowKey="#{id}" var="id"
paginator="true" rows="10" paginatorPosition="bottom"
paginatorAlwaysVisible="false" rowSelectMode="checkbox"
rowsPerPageTemplate="10,20,30,50">
<p:column selectionMode="multiple" />
<p:ajax event="toggleSelect"
update="#this"listener="#backingBean.selectAllCheckboxes}"/>
</p:dataTable>
This is my xhtml code containing a datatable using row expansion. Using primefaces 4.0, jsf mozarra 2.2.4
<p:dataTable id="myTable" value="#{myBean.lazyModel}" var="dd"
rowKey="#{dd.hashCode()}" paginator="true"
selection="#{myBean.myModel.selectedRecords}" rows="#{myBean.pageSize}"
paginatorPosition="top"
paginatorTemplate="{CurrentPageReport} {FirstPageLink}
{PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,20,50,100" widgetVar="dataTable"
currentPageReportTemplate="(Number of Records: {totalRecords})"
lazy="true">
<p:ajax event="rowToggle" listener="#{myBean.onRowToggle}" process="#this"/>
<p:column>
<p:rowToggler />
</p:column>
<p:column selectionMode="multiple" id="select" />
<p:column id="cpn" headerText="#{messages['cpn']}"
filterMatchMode="contains" sortBy="#{dd.cpn}" filterBy="#{dd.cpn}">
<p:inputText id="cpnid" value="#{dd.cpn}" />
</p:column>
<p:column id="user" headerText="#{messages['user']}"
filterMatchMode="contains" sortBy="#{dd.number}"
filterBy="#{dd.number}">
<p:inputText id="addid" value="#{dd.number}" />
</p:column>
:
:
<p:rowExpansion id="rowExpansion">
<p:panelGrid>
<p:row>
<p:column>
<h:outputText value="#{messages['name']}" />
</p:column>
<p:column>
<p:inputText id="name" name="txtBox" value="#{dd.name}" />
</p:column>
<p:column>
<h:outputText value="#{messages['ageGroup']}" />
</p:column>
<p:column id="agecol">
<p:selectOneMenu id="agegrp" value="#{dd.agegrp}">
<f:selectItem itemLabel="21-25" itemValue="21-25" />
<f:selectItem itemLabel="26-30" itemValue="26-30" />
</p:selectOneMenu>
</p:column>
</p:row>
</p:panelGrid>
</p:rowExpansion>
</p:dataTable>
Now I expanded a row and entered name and selected age group and collapsed the row. If I reexpand the same row I couldn't see the values I have entered. When I debugged on collapsing the row The name field and age grp fields setters are called with null parameters.
If I remove the ajax rowToggle event then there is no request is sent to the server on row collapse.
All the examples I found are showing only static data on row expansion.
Is there any way to process data user entered on row collapse?
Any help is highly appreciated.
I had the same problem. Do you use this datatable in a dialog?
Try set dynamic=false in parent dialog.
Dynamic dialog may override your ajax request
Try to add <p:ajax partialSubmit="true" /> inside each input forms
Just remove sortBy from child table.
It's works to me.
Or,
In xhtml file (MasterDataTable):
<p:ajax event="rowToggle" listener="#{superView.ontoggle()}" />
On View file:
public void ontoggle() {
UIComponent table = FacesContext.getCurrentInstance().getViewRoot().findComponent("form:MasterDataTable:ChildDataTable");
if (table != null) {
table.setValueExpression("sortBy", null);
}
}
I am having difficulties sorting a dynamic dataTable
dataTable
<h:form prependId="false" id="Main_Form">
<p:dataTable id="dataTable" var="c" value="#{databaseSearch.customerList}"
paginator="true" rows="10" paginatorAlwaysVisible="false"
paginatorTemplate="Page {CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} Rows per page {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15,30" draggableColumns="True">
<p:column sortBy="#{c.machine}" headerText="Machine">
<h:outputText value="#{c.machine}" />
</p:column>
<p:column sortBy="#{c.company}" headerText="Company">
<h:outputText value="#{c.company}" />
</p:column>
<p:column sortBy="#{c.contact}" headerText="Contact">
<h:outputText value="#{c.contact}" />
</p:column>
<p:column sortBy="#{c.phone}" headerText="Phone">
<h:outputText value="#{c.phone}" />
</p:column>
<p:column sortBy="#{c.email}" headerText="Email">
<h:outputText value="#{c.email}" />
</p:column>
<p:column exportable="false" headerText="Modify">
<center>
<p:commandButton id="basic" value="Update"
action="#{updateEntry.setMachine(c.machine)}"
oncomplete="dlg1.show();"
styleClass="ui-Machinebutton" update=":Update_Entry"/>
<p:tooltip for="basic" value="Update/Delete Database Entry"
showEffect="fade" hideEffect="fade" />
</center>
</p:column>
</p:dataTable>
</h:form>
I am using a #SessionScoped bean where databaseSearch.customerList would query the database and populate the dataTable. When I click on the column name to sort, the sort arrow mark changes but the table contents do not sort.
I am using PF 3.4.2
If you are querying your database in your getCustomerList method in every request this will not work. You may try with a local variable
public class DatabaseSearch{
private List<C> customerList;
public List<C> getCustomerList () {
if (customerList == null)
customerList = dao.getcustomerList();
return customerList ;
}
}
I'm having what I can call a strange behavior.
I have a page with a panel with several drops downs for search purposes and a datatable in it to display the results.
By default when the page is loaded the values get initialized by a PostContruct init().
I can perform my search without any problem including updating the datatable.
Now, the part where it gets hard for me is the following:
I have a list of tickets with Open/Closed state. My search can be performed with either Open/Closed/ALL.
By default the datatable is loaded with only the open tickets and I can select them and redirect to another page using the selectedRow value.
When I choose to filter by Closed status and I click the button to search, the datatable gets updated I can select the rows but when I try to open any page I get a null pointer exception in the bean.
If I choose all, the datatable gets updated, I can select rows but I can only open the pages with the data that was showed in the first page load, so basically only the tickets that are in the open state. Those that are in Closed that I cannot open them
I'm using RequestScoped bean, I would like to have somehints what could be the problem for the selectRow not work with the new added data.
<ui:define name="content">
<h:form id="searchForm">
<p:panelGrid id="searchPanel" style="width: 1000px" styleClass="ticketsPanel">
<p:row>
<p:column>
<p:outputLabel for="lstStatus" value="Status"></p:outputLabel>
</p:column>
<p:column>
<p:selectOneMenu id="lstStatus" value="#{ticketController.searchStatus}">
<f:selectItem itemValue="Open" itemLabel="Open"></f:selectItem>
<f:selectItem itemValue="Closed" itemLabel="Closed"></f:selectItem>
<f:selectItem itemValue="ALL" itemLabel="ALL"></f:selectItem>
</p:selectOneMenu>
</p:column>
</p:row>
<f:facet name="footer">
<p:row>
<p:column colspan="6" style="alignment-adjust: middle">
<p:commandButton value="Search" action="#{ticketController.search()}" update=":searchForm:lstTicketsTable"></p:commandButton>
<p:commandButton value="Create" action="/tickets/createticket.xhtml?faces-redirect=true"></p:commandButton>
<p:commandButton value="View" action="#{ticketController.doUpdateTicket()}"></p:commandButton>
</p:column>
</p:row>
</f:facet>
</p:panelGrid>
<p:dataTable id="lstTicketsTable" selectionMode="single" paginator="true"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {CurrentPageReport} {RowsPerPageDropdown}"
rowsPerPageTemplate="10,15,50" rows="10" paginatorPosition="bottom"
value="#{ticketController.ticketList}" selection="#{ticketController.selectedTicket}" var="_tl" rowKey="#{_tl.number}">
<p:column headerText="Ticket NR">
<p:outputLabel value="#{_tl.number}"></p:outputLabel>
</p:column>
<p:column headerText="Summary">
<p:outputLabel value="#{_tl.summary}"></p:outputLabel>
</p:column>
<p:column headerText="Contact From">
<p:outputLabel value="#{_tl.contactfrom}"></p:outputLabel>
</p:column>
<p:column headerText="Researcher">
<p:outputLabel value="#{_tl.researcher.email == null ? '' : _tl.researcher.email}"></p:outputLabel>
</p:column>
<p:column headerText="NSN SR">
</p:column>
<p:column headerText="SR / CR">
</p:column>
<p:column headerText="Release">
<p:outputLabel value="#{_tl.release}"></p:outputLabel>
</p:column>
<p:column headerText="Status">
<p:outputLabel value="#{_tl.status}"></p:outputLabel>
</p:column>
<p:column headerText="Age">
<p:outputLabel value="#{_tl.startdate}"></p:outputLabel>
</p:column>
<p:column headerText="Priority">
<p:outputLabel value="#{_tl.priority}"></p:outputLabel>
</p:column>
</p:dataTable>
</h:form>
</ui:define>
And the backing bean functions doUpdateTicket is the one being called in the View button and the Search the one that updates the list of the datatable.
public void doUpdateTicket() {
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
try {
ec.redirect("/SupportSite/faces/tickets/updateticket.xhtml?tnr=" + this.selectedTicket.getNumber().toString());
} catch (IOException ex) {
Logger.getLogger(TicketController.class.getName()).log(Level.SEVERE, null, ex);
}
}
public void search() {
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
if (this.searchTicketNR != null) {
Ticket t = tjc.findTicket(Integer.parseInt(this.searchTicketNR));
if (t != null) {
try {
//This works when search by ticket number only
ec.redirect("/SupportSite/faces/tickets/updateticket.xhtml?tnr=" + t.getNumber().toString());
} catch (IOException ex) {
Logger.getLogger(TicketController.class.getName()).log(Level.SEVERE, null, ex);
}
}
} else if (this.getSearchStatus() != "ALL") {
setTicketList(tjc.findTicketByStatus(this.getSearchStatus()));
this.init();
} else {
setTicketList(tjc.findTicketEntities());
this.init();
}
}