losing request parameter in jsf for second ajax poll call - ajax

I'm facing a problem with poll request, the first call is ok and the second is loosing the request parameter. Below is the code:
<h:form id="form">
<p:poll interval="10" listener="${emsstatbean.getEmsStat_list(request.getParameter('para'))}" update="emstatTable" />
<p:dataTable id="emstatTable" var="emsstat" value="${emsstatbean.getEmsStat_list(request.getParameter('para'))}" emptyMessage="No statistic found with given criteria" styleClass="table table-striped table-bordered table-hover" >
<p:column headerText="Server Hostname" >
<h:outputText value="#{emsstat.id.timeStamp}" />
</p:column>
<p:column headerText="Os name" >
<h:outputText value="#{emsstat.upTime}" />
</p:column>
<p:column headerText="Os name" >
<h:outputText value="${emsstat.state}" />
</p:column>
</p:dataTable>
</h:form>
and this is the bean class:
#ManagedBean(name = "emsstatbean")
public class EmsStatBean implements Serializable
{
public List<TibcoEmsStat> getEmsStat_list(int p)
{
return service.listEmsStats(p);
}
#ManagedProperty("#{emsStatService}")
EmsStatService service;
#PostConstruct
public void init()
{
}
public void setService(EmsStatService service)
{
this.service = service;
}
}
This is the URL called: content/public/TibcoEmsStat.xhtml?para=254
So when I paste that on browsers I'm getting the data table with all rows, but when I wait 10 sec I don't see content and I get "No statistic" found with given criteria, because parameter is empty.
Can you please help me to understand where is the issue?

this is how i fixed after reviewing some suggested link
added to the bean:
#ViewScoped
and a variable to store the id
public int ems_inst;
public int getEms_inst() {
return ems_inst;
}
public void setEms_inst(int ems_inst) {
this.ems_inst = ems_inst;
}
on the xhtml i did:
<f:metadata>
<f:viewParam name="ems_inst" value="#{emsstatbean.ems_inst}" />
</f:metadata>
<h:form id="form">
<p:poll interval="10"
listener="${emsstatbean.getEmsStat_list(emsstatbean.ems_inst)}" update="emstatTable" />
<p:dataTable id="emstatTable" var="emsstat" value="${emsstatbean.getEmsStat_list(emsstatbean.ems_inst)}"
all now is working fine
thanks

Related

Modal edit dialog on Primefaces with JSF

I'm trying to create some CRUD JSF application with edit/new screen implemented as a modal dialog. The problem is that I can't find a way how to make new and edit operation done by this dialog performed with ajax. With delete all was very simple (just ajax="true" option).
Here is a code of button which is used to show the dialog
<h:form id="dataForm">
<div class="ui-g">
<div class="ui-g-12 ui-md-9">
<p:dataGrid var="product" value="#{products.productList}" columns="3" layout="grid"
rows="12" paginator="true" id="products"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="6,12,16">
<f:event type="preRenderView" listener="#{products.preloadProductList}" />
<f:facet name="header">
Products
</f:facet>
<p:panel header="#{product.name}" style="text-align:center">
<h:panelGrid columns="1" style="width:100%">
<h:outputText value="#{product.name}"/>
<h:outputText value="#{product.price}"/>
<%-- Here new/edit dialog window is opened --%>
<p:commandLink update=":dataForm:productDetail" oncomplete="PF('productDialog').show()">
Edit
<f:setPropertyActionListener value="#{product}" target="#{products.product}"/>
</p:commandLink>
<p:commandLink update=":dataForm" action="#{products.deleteAction(product)}" ajax="true">
Delete
</p:commandLink>
</h:panelGrid>
</p:panel>
</p:dataGrid>
<ui:include src="WEB-INF/dialogs/edit_product.xhtml"/>
</div>
</div>
</h:form>
Here is dialog window which is moved to separete file edit_product.xhtml
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<p:dialog header="Product Info" widgetVar="productDialog" modal="true" showEffect="fade"
hideEffect="fade"
resizable="false">
<p:outputPanel id="productDetail" style="text-align:center;">
<p:panelGrid columns="2" rendered="#{not empty products.product}"
columnClasses="label,value">
<h:outputText value="Id:"/>
<h:outputText value="#{products.id}"/>
<h:outputText value="Name"/>
<h:inputText value="#{products.name}"/>
<h:outputText value="Price"/>
<h:inputText value="#{products.price}"/>
</p:panelGrid>
<h:commandButton value="Save" action="#{products.saveProduct}"/>
</p:outputPanel>
</p:dialog>
</ui:composition>
Here is Managed bean which is used by the Product dataGrid and dialog window.
#ManagedBean(name = "products")
#SessionScoped
public class ProductsBean {
private static final Logger logger = LoggerFactory.getLogger(ProductsBean.class);
#Inject
private ProductRepository productRepository;
private Product product;
private Collection<Product> productList;
public void preloadProductList(ComponentSystemEvent event) throws AbortProcessingException {
productList = productRepository.getAll();
}
public String getId() {
return String.valueOf(product.getId());
}
public void setId(String id) {
product.setId(Long.valueOf(id));
}
public String getName() {
return product.getName();
}
public void setName(String name) {
product.setName(name);
}
public int getPrice() {
return product.getPrice();
}
public void setPrice(int price) {
product.setPrice(price);
}
public Product getProduct() {
return this.product;
}
public void setProduct(Product product) {
this.product = product;
}
public Collection<Product> getProductList() {
logger.info("Get product list");
return productList;
}
public void newProductAction() {
this.product = new Product();
}
public void deleteAction(Product product) {
logger.info("Delete product");
productRepository.remove(product);
}
public void saveProduct() {
productRepository.merge(product);
}
}
No matter if I add ajax option or not the whole window is reloaded after Save button is pressed. Could you show me the right direction for the implementation, please?
P.S. If you need more code to answer you can find it here:
Main page with Product table https://github.com/usharik/GeekBrainsJavaEE/blob/master/lesson5-jpa/src/main/webapp/index.xhtml
Edit/New dialog https://github.com/usharik/GeekBrainsJavaEE/blob/master/lesson5-jpa/src/main/webapp/WEB-INF/dialogs/edit_product.xhtml

PF SetPropertyActionListener breaks after first time

i've a problem that's driving me crazy! I have a component which renders a panel that have links on a footer. This links have, among other things, a title and HTML content I want to show. The idea is basically that when a link is clicked, the content of the page is changed via ajax and the html content of the link is shown (The footer remains on the page). Debbuging I've noticed that the first time a link is clicked the content does change, but then it doesn't. The setPropertyActionListener of the p.commandlinks in my composite component aren't executed any more after first time. I'have debbuged the project and this seems to be the problem, but I can't figure out why
Part of my composite component. Tryed setting an onstart and oncomplete js functions on the command link, and both are executed but the actionListeners aren't.
<cc:interface>
<cc:attribute name="compId"/>
<cc:attribute name="title"/>
<cc:attribute name="bean"/>
...
</cc:interface>
<!-- IMPLEMENTATION -->
<cc:implementation>
<p:panel id="#{cc.attrs.compId}" header="#{cc.attrs.title}"
widgetVar="#{cc.attrs.compId}"
styleClass="#{cc.attrs.styleClass}">
<h:form>
<p:dataList id="datalist-#{cc.attrs.compId}" value="#{cc.attrs.bean.currentList}"
type="definition" widgetVar="datalist-#{cc.attrs.compId}"
var="items" >
<p:commandLink action="#{navBean.active}" update="#([id$=content])" styleClass="link"
value="#{items.descrInLang}" rendered="#{items.typeUrl eq 0}">
<f:setPropertyActionListener value="infoPage" target="#{navBean.selection}"/>
<f:setPropertyActionListener value="#{items.descrInLang}" target="#{infoPage.title}" />
<f:setPropertyActionListener value="#{items.HTMLContent}" target="#{infoPage.HTMLContent}"/>
</p:commandLink>
</p:dataList>
</h:form>
</p:panel>
</cc:implementation>
Part of my Navigation Bean
public void active() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException {
setAlbums(selection.equals("albums"));
setBand(selection.equals("band"));
setConcerts(selection.equals("concerts"));
setContacts(selection.equals("contacts"));
setHome(selection.equals("home"));
setSiteMap(selection.equals("siteMap"));
setInfoPage(selection.equals("infoPage"));
}
public void setSelection(String selection) {
this.selection = selection;
}
public boolean isInfoPage() {
return infoPage;
}
public void setInfoPage(boolean infoPage) {
this.infoPage = infoPage;
}
The bean which stores the title & HTML Content to show. After the first click on the link, the getters of Title & HTML content are executed, but the setters aren't (as declared in the setPropertyActionListeners)
#ManagedBean
#SessionScoped
public class InfoPage implements Serializable {
private String title;
private String HTMLContent;
public InfoPage() {
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getHTMLContent() {
return HTMLContent;
}
public void setHTMLContent(String HTMLContent) {
this.HTMLContent = HTMLContent;
}
}
The content part of the template which indicates what content should be shown according to the selected page on the NavBean. I pass the HTML content and the title of the infoPage as a parameter
<h:head>
</h:head>
<h:body>
<!-- the all containing file -->
<ui:composition template="template.xhtml">
<ui:define name="content">
<h:panelGroup layout="block" id="content">
<h:panelGroup layout="block" rendered="#{navBean.home}">
<ui:include src="homecontent.xhtml"/>
</h:panelGroup>
....
<h:panelGroup layout="block" rendered="#{navBean.infoPage}">
<ui:include src="infoPage.xhtml">
<ui:param name="title" value="#{infoPage.title}"/>
<ui:param name="infoContent" value="#{infoPage.HTMLContent}"/>
</ui:include>
</h:panelGroup>
</h:panelGroup>
</ui:define>
</ui:composition>
</h:body>
The info Page.
<h:form id="infoPageForm">
<p:panel id="infoPagePanel" header="#{title}">
<h:panelGrid columns="1" cellpadding="10">
<h:outputText escape="false" value="#{infoContent}" />
</h:panelGrid>
</p:panel>
</h:form>
Thanks for your time!

Primefaces ajax pagination not working

I have following jsf page, in which datatable is populated via ajax request from database. Problem is, after pushing another page button on pagination bar, table shows no results. Changing scope of backing bean to session helps, but it is not a solution. Why it is happening?
<h:form>
<h:panelGrid columns="2" cellpadding="8" style="width: 545px">
<h:panelGroup>
<p:outputLabel value="Client name: " for="searchString" />
<br />
<p:inputText id="searchString" title="searchString" value="#{findClientBean.searchString}" />
</h:panelGroup>
<h:panelGroup>
<br />
<p:message for="searchString" />
</h:panelGroup>
<p:commandButton value="Search" styleClass="pCommandButton" >
<f:ajax execute="searchString" listener="#{findClientBean.findClient}" render=":resultTable" />
</p:commandButton>
</h:panelGrid>
</h:form>
<br />
<p:dataTable id="resultTable" var="client" value="#{findClientBean.resultList}" paginator="true" rows="10"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15" paginatorPosition="bottom">
<p:column headerText="Search results">
<h:outputLink value="../temp.xhtml?id=#{client.id}">#{client.firstName} #{client.lastName}</h:outputLink>
</p:column>
</p:dataTable>
<h:form>
Backing bean code:
#Named
#RequestScoped
public class FindClientBean implements Serializable {
#Inject
private ClientDAO clientDAO;
#NotNull(message="Search string cannot be empty")
private String searchString;
private List<Client> resultList;
public void findClient() {
resultList = clientDAO.findClientByNameOrLastnamePart(searchString);
}
public void setResultList(List<Client> resultList) {
this.resultList = resultList;
}
public List<Client> getResultList() {
return resultList;
}
public String getSearchString() {
return searchString;
}
public void setSearchString(String searchString) {
this.searchString = searchString;
}
}
Your Client resultList is being populated whenever the user presses the Search button.
As the collection is inside a RequestScoped bean, the resultList will be erased as soon as it is sent back to the View (along with the entire bean).
As a result, when the user tries to navigate to another page (thus making a second request) the component won't find a populated resultList anymore and a "No records found" message will be displayed.
"Promote" you bean to ViewScoped (or any scope that would make your bean live longer).
#Named
#ViewScoped
public class FindClientBean implements Serializable{
(...)
}

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());
}

DataTable Order by column erase values

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>

Resources