DataTable Order by column erase values - ajax

I have PrimeFaces dataTable that is been filled by a Ajax call.
When I click on a column title, to order its values, the values disappear.
<p:commandButton value="Pesquisar" actionListener="#{requestController.listRequests}" update="dataTable" />
Here is my view:
<p:dataTable id="dataTable" var="order" value="#{requestController.backing.requestsList}"
paginator="true" rows="10"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}">
<p:column sortBy="#{order.companyRequest}">
<f:facet name="header">
<h:outputText value="Pedido" />
</f:facet>
<h:outputText value="#{order.companyRequest}" />
</p:column>
<p:column sortBy="#{order.company.companyName}">
<f:facet name="header">
<h:outputText value="Cliente" />
</f:facet>
<h:outputText value="#{order.company.companyName}" />
</p:column>
<p:column sortBy="#{order.emissionDate}">
<f:facet name="header">
<h:outputText value="Data" />
</f:facet>
<h:outputText value="#{order.emissionDate}">
<f:convertDateTime pattern="dd/MM/yyyy"/>
</h:outputText>
</p:column>
<p:column sortBy="#{order.requestSituation.description}">
<f:facet name="header">
<h:outputText value="Status" />
</f:facet>
<h:outputText value="#{order.requestSituation.description}" />
</p:column>
<p:column>
<f:facet name="header">
</f:facet>
<h:form>
<h:commandLink value="Detalhes"/>
</h:form>
</p:column>
</p:dataTable>
EDIT
RequestController
#ManagedBean
#RequestScoped
public class RequestController implements Serializable
{
private RequestBacking backing;
public RequestController()
{
backing = new RequestBacking();
}
public void changeEventListener(ValueChangeEvent e)
{
backing.requestSearchType = e.getNewValue().toString();
}
public void change()
{
switch (backing.requestSearchType)
{
case "data":
backing.mask = "99/99/9999";
backing.maskSize = "10";
break;
case "cnpj":
backing.mask = " 99.999.999/9999-99";
backing.maskSize = "20";
break;
default:
backing.mask = "";
backing.maskSize = "50";
}
}
public void listRequests() throws ParseException
{
CompanyVO companyVO = new CompanyVO();
switch (backing.requestSearchType)
{
case "cnpj":
companyVO.setCnpj(backing.requestSearchValue);
break;
case "cliente":
companyVO.setCompanyName(backing.requestSearchValue);
break;
case "pedido":
backing.requestVO.setCompanyRequest(Integer.parseInt(backing.requestSearchType));
break;
}
SupplierVO supplierVO = new Support().getUserSession().getSupplier();
backing.requestVO.setEmissionDate(new Support().convertDate(backing.requestSearchValue));
backing.requestVO.setSupplier(supplierVO);
backing.requestVO.setCompany(companyVO);
backing.requestsList = new ArrayList<>(backing.getBo().getRequest(backing.requestVO));
if (backing.requestsList.isEmpty())
{
FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_WARN, "Nenhum registro encontrado!", null);
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
backing.requestsList = null;
}
}
..backing getter and setter
}
My requestsList is on my RequestBacking where I have all my getters and setters, please correct me if there is a better way of doing this, I'm using it because it leaves my controller cleaner.
public List<RequestVO> requestsList;

Apparently the value="#{requestController.backing.requestsList}" didn't return the same value as it did on the initial request. That can happen if it's a request scoped bean and/or if the requestsList is populated on every request based on a request based variable.
That's just a design mistake. Put the managed bean in the view scope and make sure that you aren't doing any business logic in a getter method. The nested class backing is also suspicious or it must be a poor naming.
See also:
Why JSF calls getters multiple times
How to choose the right bean scope?
Update in a nutshell, your bean should look something like this:
#ManagedBean
#ViewScoped
public class Orders {
private String query; // +getter +setter
private List<Order> results; // +getter (no setter required)
#EJB
private OrderService service;
public void search() {
results = service.search(query);
}
// Add/generate normal getters/setters (don't change them!)
}
and your view should look like this:
<h:form>
<p:inputText value="#{orders.query}" />
<p:commandButton value="Search" action="#{orders.search}" update=":tableForm" />
</h:form>
<h:form id="tableForm">
<p:dataTable value="#{orders.results}" var="order" ... rendered="#{not empty orders.results}">
...
</p:dataTable>
<h:outputText value="No results found" rendered="#{facesContext.postback and empty orders.results}" />
</h:form>

Related

OneMenu & 2 ajax inside won't work

I'm facing a huge problem since 2 weeks.
I tested 2 ajax method one by one and they work. But when I want to have both in a oneMenu, the dropdown supposed to update the third oneMenu of the page does'nt work.
<h:body>
<h:form>
<p:growl id="growl" showDetail="true" />
<p:outputLabel value="Sélectionner une section " for="sectionBox"/>
<p:selectOneMenu id="sectionBox"
value="#{evaluationViewController.currentSection}"
converter="sectionConverter"
var="c"
filter="true"
filterMatchMode="startsWith"
effect="fade"
>
<p:ajax listener="#{evaluationViewController.onSectionSelected}" update="ue,ueO,growl"/>
<f:selectItem itemLabel="Sélectionnez uen section" itemValue="" noSelectionOption="true"/>
<f:selectItems value="#{evaluationViewController.currentSections}"
var="currentSection"
itemLabel="#{currentSection.name}"
itemValue="#{currentSection}"
/>
<p:column>
<h:outputText value="#{c.name}"/>
</p:column>
</p:selectOneMenu>
<p:outputLabel value="Sélectionner une UE " for="ue"/>
<p:selectOneMenu id="ue"
value="#{evaluationViewController.ue}"
converter="ueConverter"
var="u"
filter="true"
filterMatchMode="startsWith"
>
<p:ajax listener="#{evaluationViewController.onUeSelected}" update="ueO,growl"/>
<p:ajax event="change" update="capacities" listener="#{evaluationViewController.listenerCapacitiesUpdate}"/>
<f:selectItem itemLabel="Sélectionnez une UE" itemValue="" noSelectionOption="true"/>
<f:selectItems value="#{evaluationViewController.ues}"
var="ues"
itemLabel="#{ues.name}"
itemValue="#{ues}"
/>
<p:column>
<h:outputText value="#{u.name}"/>
</p:column>
</p:selectOneMenu>
<p:outputLabel value="Sélectionner l'UE enseignée" for="ueO"/>
<p:selectOneMenu id="ueO"
value="#{evaluationViewController.organizedUe}"
converter="organizedUeConverter"
var="o"
filter="true"
filterMatchMode="startsWith"
>
<f:selectItem itemLabel="Sélectionnez une année" itemValue="" noSelectionOption="true"/>
<f:selectItems
value="#{evaluationViewController.organizedUes}"
var="organizedUes"
itemLabel="#{organizedUes.name}"
itemValue="#{organizedUes}"
/>
<p:column>
<h:outputText value="#{o.name}"/>
</p:column>
<p:column>
<h:outputText value="#{o.level.name}"/>
</p:column>
</p:selectOneMenu>
<p:separator/>
<p:separator/>
<p:dataTable id="capacities"
var="cap"
value="#{evaluationViewController.capacities}"
editable="true"
editMode="cell"
widgetVar="cellCap"
>
<f:facet name ="header">
Capacitées
</f:facet>
<p:ajax event="cellEdit"
listener="#{evaluationViewController.onCellEdit}"
update="#this"/>
<p:column headerText="Dénomination">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{cap.name}"/></f:facet>
<f:facet name="input"><p:inputText value="#{cap.name}" style="width: 30%" label="Dénomination"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Description">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{cap.description}"/></f:facet>
<f:facet name="input"><h:inputText value="#{cap.description}" style="width: 90%" label="Description"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Réussite obligatoire">
<p:selectBooleanCheckbox value="#{cap.isThresholdOfSuccess}" style="alignment-adjust: central"/>
</p:column>
</p:dataTable>
<p:separator/>
</h:form>
</h:body>
I followed the primefaces demo as well for the bean :
public class EvaluationViewController implements Serializable {
#EJB
private SectionFacade ejbSectionFacade;
private List<Section> currentSections;
private Section currentSection;
#EJB
private UeFacade ejbUeFacade;
private List<Ue> ues;
private Ue ue;
#EJB
private OrganizedUeFacade ejbOrganizedUeFacade;
private List<OrganizedUe> organizedUes;
private OrganizedUe organizedUe;
#EJB
private CapacityFacade ejbCapacity;
private List<Capacity> capacities;
private Capacity capacity;
#PostConstruct
public void init() {
currentSections = ejbSectionFacade.findAll();
ues = new ArrayList<>();
organizedUes = new ArrayList<>();
capacities = new ArrayList<>();
}
public void onSectionSelected() {
if (currentSection != null && !currentSection.getName().equals("")) {
ues = ejbUeFacade.findBySection(currentSection);
ue = null;
capacity = null;
FacesMessage facesMessage = new FacesMessage("Sélection", currentSection.getName());
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
} else {
ues = null;
}
}
public void onUeSelected() {
if ((currentSection != null && !currentSection.getName().equals(""))
&& (ue != null && !ue.getName().equals(""))) {
organizedUes = ejbOrganizedUeFacade.findByUe(ue);
capacities = ejbCapacity.findByUe(ue);
capacity = null;
FacesMessage facesMessage = new FacesMessage("Sélection de l'UE : ", ue.getName());
FacesContext.getCurrentInstance().addMessage(null, facesMessage);
} else {
organizedUes = null;
}
}
public void listenerCapacitiesUpdate() {
capacities = ejbCapacity.findByUe(ue);
}
The DataTable is updated and rendered but not the last oneMenu. I really don't get it. I would be very gratefull for the answer.
There are two things at hand here:
If you do not provide an explict event, then a default one is taken
You cannot add two ajax tags to the same component listening to the same event
So if in this case the default ajax event of the p:selectOneMenu is change, only the second one will be processed. Adding an explicit event other than change to the first ajax handler will make it work
Off-topic but important things you should normally do debugging issues like this:
Find the differences between the two and see and try to make them as identical as possible
See if the order plays a role by switching them
See if using a different component makes it work

Primefaces "sortBy=" doesn't work

I'm developing an application using Primefaces + JSF. My data table works, but has a problem at sort sortBy=, I tried sortBy="#{pc.rota}" but it doesn't work too:
Data table show all rows, the problem I think is sortBy= or my backing bean.
page.xhtml
<h:body>
<h:form id="pcEmulation">
<p:dataTable id="dataTablePCEMulation" var="pc" value="#{pCEmulationBean.allPCEmulation}"
rows="10"
rowsPerPageTemplate="5,30,50,100,200,300"
emptyMessage="Não foi encontrado"
>
<f:facet name="header">
PC Emulation Web
</f:facet>
<p:column headerText="PC - TX OLO's" filterValue="#{pc.filtpcn}" filterMatchMode="contains" filterBy="#{pc.filtpcn}" >
<h:outputText value="#{pc.filtpcn}" />
</p:column>
<p:column headerText="Rota" sortBy="rota" >
<h:outputText value="#{pc.rota}" />
</p:column>
<p:column headerText="Origem">
<h:outputText value="#{pc.origem}" />
</p:column>
<p:column headerText="Antigo">
<h:outputText value="#{pc.epcn}" />
</p:column>
<p:column headerText="Destino">
<h:outputText value="#{pc.destino}" />
</p:column>
<p:column headerText="PC-Novo">
<h:outputText value="#{pc.realpcn}" />
</p:column>
</p:dataTable>
<p:blockUI block="dataTablePCEMulation" trigger="dataTablePCEMulation">
LOADING<br />
<p:graphicImage value="/images/loading.gif"/><br />
<p:graphicImage value="/images/tim-banner2.png" width="100px" height="45px"/>
</p:blockUI>
</h:form>
</h:body>
Backing bean:
#ManagedBean
//#ViewScoped
#SessionScoped
public class PCEmulationBean {
public List<PCEmulation> allPCEmulation;
public List<PCEmulation> getAllPCEmulation() {
PCEmulationDAO dao = new PCEmulationDAO();
try {
allPCEmulation = dao.getAll();
} catch (ClassNotFoundException | SQLException e) {
System.out.println("Problema no metodo list : " + e);
}
return allPCEmulation;
}
}
For the sort to work you need to return the same list object each time with the getter, where in your case you are returning a new list from the dao every time. So you should only fetch a new list if the list is previously null. The code inside your getter should be as below.
if (allPCEmulation == null) {
PCEmulationDAO dao = new PCEmulationDAO();
try {
allPCEmulation = dao.getAll();
} catch (ClassNotFoundException | SQLException e) {
System.out.println("Problema no metodo list : " + e);
}
}
return allPCEmulation;
As far as I know, sortBy attribute of Datatable is applied for only Primitive Data Types and String. If rota is an object, you must create method for sorting by yourself. Alternative, using sortBy="#{pc.rota.someting}" that contain Primitive Data Types or String for sorting.

Add Dynamic Row in <p:datatable> Using <p:commandButto> and <f:ajax>

in following code commandbutton not properly work for the datatable.
<p:dataTable id="invoiceTable" var="ipsDetail"
value="#{invoiceBean.ipsDetails}" border="1">
<p:column headerText="Sr. No.">
<h:inputText id="serialN7umber" value="#{ipsDetail.serialNumber}"
size="3" />
</p:column>
<p:column headerText="Description of Goods">
<p:inputText value="#{ipsDetail.descriptionOfGoodsOrService}" />
</p:column>
<p:column headerText="HSN Code">
<p:inputText value="#{ipsDetail.hsnCode}" styleClass="Alingment" />
</p:column>
<p:column headerText="Quantity">
<p:inputText value="#{ipsDetail.quantity}" styleClass="Alingment" />
</p:column>
<p:column headerText="Rate">
<p:inputText value="#{ipsDetail.rate}" styleClass="Alingment" />
</p:column>
<p:column headerText="Percentage Discount">
<p:inputText value="hello" rendered="#{ipsDetail.percentDiscount}"
styleClass="Alingment" />
</p:column>
<p:column headerText="Amount">
<p:inputText value="#{invoiceBean.amount}" styleClass="Alingment" />
</p:column>
<f:facet name="footer">
<p:commandButton value="Add New Row" action="#{invoiceBean.addRow}" update=":form:invoiceTable">
<!-- <f:ajax execute=":form:invoiceTable" render=":invoiceTable:addColumn" /> -->
</p:commandButton>
</f:facet>
</p:dataTable>
</h:form>
I want To add dynamic row with inputtext using primefaces commandbutton in java. it work but re-render not possible.
public class InvoiceBean implements Serializable {
public List getInvoices() {
InvoiceDao invoiceDao = new InvoiceDao();
invoices = invoiceDao.getInvoiceData();
return invoices;
}
public void setInvoices(List<Invoice> invoices) {
if (invoices != null) {
this.invoices.add(new Invoice());
}
}
public void getInvoiceData() {
InvoiceDao invoiceDao = new InvoiceDao();
ipsDetail = new InvoiceProductsServicesDetail();
if ( ipsDetail != null) {
ipsDetail
.setDescriptionOfGoodsOrService(descriptionOfGoodsOrService);
ipsDetail.setHsnCode(hsnCode);
ipsDetail.setInvoiceId(invoice.getId());
ipsDetail.setPercentDiscount(percentDiscount);
ipsDetail.setQuantity(quantity);
ipsDetail.setRate(rate);
ipsDetail.setSerialNumber(serialNumber);
ipsDetail.setServiceTax((float) 12.5);
ipsDetail.setVat(5);
System.out.println("InvoiceBean.insertInvoice");
}
invoiceDao.insertInvoice(invoice, ipsDetail);
}
public Row addRow() {
Row row = new Row();
InputText inputText = new InputText();
inputText.setSubmittedValue("Hello");
Column column = new Column();
row.setParent(inputText);
column.setHeader(inputText);
column.setHeaderText("Hardik");
return row;
}
}
This Is code for add row or column with inputtext
Since you are using Primefaces you can also Update any component from ManagedBean itself using org.primefaces.context.RequestContext object.
For example:
Facelet:
<h:form id="form1">
<p:dataTable id="myTab">
...
</p:dataTable>
</h:form>
ManagedBean:
RequestContext reqCtx = Requestcontext.getCurrentInstance();
req.Ctx.update("form1:myTab");
You can't update the table from inside the table. You can do the following:
<p:dataTable id="invoiceTable" var="ipsDetail" value="#{invoiceBean.ipsDetails}"
border="1">
...
<f:facet name="footer">
<p:commandButton value="Add New Row" onclick="updateTable();">
</p:commandButton>
</f:facet>
</p:dataTable>
...
<p:remoteCommand name="updateTable" update=":form:invoiceTable"
actionListener="#{invoiceBean.addRow}" />
Thank For Your Response and Solution regarding my question is below edit addRow().
public void addRow() {
ipsDetail = new InvoiceProductsServicesDetail();
if (descriptionOfGoodsOrService != null
&& hsnCode != null && quantity != 0 && rate != 0) {
ipsDetail.setSerialNumber(serialNumber);
ipsDetail
.setDescriptionOfGoodsOrService(descriptionOfGoodsOrService);
ipsDetail.setHsnCode(hsnCode);
ipsDetail.setPercentDiscount(percentDiscount);
ipsDetail.setQuantity(quantity);
ipsDetail.setRate(rate);
ipsDetails.add(ipsDetail);
}
FacesContext facesContext = FacesContext.getCurrentInstance();
try {
DataTable table = (DataTable) facesContext.getViewRoot()
.findComponent("form:invoiceTable");
UIComponent uiTable = ComponentUtils.findParentForm(facesContext,
table);
final AjaxBehavior behavior = new AjaxBehavior();
RowEditEvent rowEditEvent = new RowEditEvent(uiTable, behavior,
table.getRowData());
rowEditEvent.setPhaseId(PhaseId.UPDATE_MODEL_VALUES);
table.broadcast(rowEditEvent);
} catch (AbortProcessingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

PrimeFaces commandButton ajax does not work

I have simple JSF page and simple backing bean. I have p:commandButton on the page and p:datatable. With commandButton I need to update dataTable with ajax, but it does not happens. What could be the reason?
Here is the page:
<ui:define name="content">
<h2>#{menu['management.roles.perms']}</h2>
<h:form id="form">
<p:fieldset style="border: 0px" toggleable="false" collapsed="false">
<p:tabView>
<p:tab title="#{messages['roles']}">
<p:dataTable id="dataTable" value="#{rolesBean.roles}" var="role"
editable="true" rows="10" rowKey="#{role.id}">
<p:ajax event="rowEdit" listener="#{rolesBean.onEdit}"/>
<f:facet name="footer">
<p:commandButton value="#{misc['add.role']}"
actionListener="#{rolesBean.addRole}" update="dataTable"/>
</f:facet>
<p:column headerText="#{misc['name.database']}">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{role.name}"/>
</f:facet>
<f:facet name="input">
<h:inputText value="#{role.name}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="#{misc['date']}">
<f:facet name="output">
<h:outputText value="#{role.creationDate}">
<f:convertDateTime pattern="dd.MM.yyyy" />
</h:outputText>
</f:facet>
</p:column>
<p:column headerText="#{misc['description']}">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{role.description}"/>
</f:facet>
<f:facet name="input">
<h:inputText value="#{role.description}"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="#{messages['edit']}">
<p:rowEditor />
</p:column>
</p:dataTable>
</p:tab>
<p:tab title="#{messages['perms']}">
</p:tab>
<p:tab title="#{clients['history']}">
</p:tab>
</p:tabView>
</p:fieldset>
</h:form>
</ui:define>
And here is the code of backingBean:
#ViewScoped
#ManagedBean(name = "rolesBean")
public class RolesViewBean extends BasicViewBean<Role> {
private static final long serialVersionUID = 27377603187254821L;
#Inject
RoleDao dao;
private List<Role> roles;
#Override
protected BasicDao<Role> getDAO() {
return dao;
}
public void onEdit(RowEditEvent event){
this.entity = (Role) event.getObject();
dao.update(this.entity);
}
public void addRole(){
roles.add(new Role());
}
public List<Role> getRoles() {
roles = dao.getRoleList();
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
}
At first glance, the problem is that your addRole method modifes the "roles" list, while the getRoles (which gets called by the dataTable) resets it to whatever is saved in the database.
So your datatabe gets updated, it' just that it gets updated with the same values.
Think about that ;)

Navigate to another page on rowselect of datatable in primefaces

I have a primefaces datatable where number of records are displaying.
I want navigate to another page on the rowSelect event (to edit the selected entity for example).
The closest sample/demo I could find was use the p:ajax tag to bind the rowSelect event to a listener method
http://www.primefaces.org/showcase-labs/ui/datatableRowSelectionInstant.jsf
I also got one article for the same http://forum.primefaces.org/viewtopic.php?f=3&t=14664
, I tried to implement in same as they did.But it also didn't worked.
I am trying in this way and guide me If I missed anything.
<p:dataTable var="product" value="#{addPatientBB.patientAddList}" paginator="true" rows="10"
selection="#{addPatientBB.pat}" selectionMode="single">
<p:ajax event="rowSelect" listener="#{addPatientBB.onRowSelect}" />
<p:column>
<f:facet name="header">
<h:outputText value="FirstName" />
</f:facet>
<h:outputText value="#{product.firstName}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Email" />
</f:facet>
<h:outputText value="#{product.email}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Gender" />
</f:facet>
<h:outputText value="#{product.gender}" />
</p:column>
</p:dataTable>
And Backing bean is :
#ManagedBean
#ViewScoped
public class AddPatientBB implements Serializable
{
private Patient pat;
public Patient getPat()
{
System.out.println("tried to get pat");
return pat;
}
public void setPat(Patient pat)
{
this.pat = pat;
System.out.println("tried to set pat");
}
public void onRowSelect()
{
System.out.println("inside onRow select Method");
ConfigurableNavigationHandler configurableNavigationHandler = (ConfigurableNavigationHandler) FacesContext.getCurrentInstance().getApplication().getNavigationHandler();
System.out.println("navigation objt created");
configurableNavigationHandler.performNavigation("Page?faces-redirect=true");
// Page is my navigation page where I wish to navigate named as
// "Page.xhtml"
System.out.println("Navigation executed");
}
}
So how can I navigate to another page on rowselect event? and how can display its values after navigationg the form.
I am able to go inside onRowSelect() method , actually problem is he is not able to get or understood that path :
configurableNavigationHandler.performNavigation("Page?faces-redirect=true");
so he is not able to print any logs after this line.
why is it so? is it because of I am using Liferay?
Pla guide me.
Well i think the onRowSelect is never executed because you defined it wrong.
Try this:
public void onRowSelect(SelectEvent event)
{
FacesContext.getCurrentInstance().getExternalContext().redirect("page.xhtml?id=" +pat.getId());
}
If u are using FacesServlet then use.jsf instead of .xhtml
public void onRowSelect(SelectEvent event)
{
FacesContext.getCurrentInstance().getExternalContext().redirect("page.jsf?id="+pat.getId());
}

Resources