Updating dataTable data after clicking on Search button - ajax

Once page xyz.xhtml gets loaded, I am displaying 10 records.
<h:dataTable var="c" value="#{userServiceBean.showTop10Applicant()}"
styleClass="order-table"
headerClass="order-table-header"
rowClasses="order-table-odd-row,order-table-even-row"
border="1" id="appListDataTable" width="100%">
<h:column>
<f:facet name="header">
Applicant Name
</f:facet>
#{c.displayName}
</h:column>
</dataTable>
In showTop10Applicant() I'm returning 10 random records.
Above this dataTable, I have search textbox and search button. I have used ajax for checking the data.
<h:inputText id="searchApplicant" value="#{userDataBean.toSearch}" /> +
<h:commandButton value="Search" action="#{userServiceBean.searchApplicantsByCriteria()}">
<f:ajax execute="searchApplicant" render=":appListDataTable"/>
</h:commandButton>
In searchApplicantsByCriteria() I am displaying all records that I have (right now I am not checking for any criteria).
BUT, when I click on Search, I get same 10 records back as earlier.
Could anyone help where I am getting wrong.
Update 1
Below is what I want to do.
I want to search some persons that are there in database. When the page gets loaded, I am displaying random 10 persons using dataTable (using method showTop10Applicant()).
In Search textbox, I write abc and click on Search button. What I want is that the dataTable that is already present (where we are displaying 10 random records) get updated with the finding of abc. Lets say there are 2 person whose name contains abc, then I should get only list of these two persons.
Hope I am clear now. Let me know incase if there are any questions.
Update 2
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:body>
<ui:composition template="../layout/homeLayout.xhtml">
<ui:define name="content">
<center>
<h2>
<u>
<h:outputText value="Manage Applicants"></h:outputText>
</u>
</h2>
</center>
<br />
<h:form id="myForm002" prependId="false">
<div align="right">
<h:inputText id="searchApplicant" value="#{userDataBean.toSearch}" /> +
<h:selectOneMenu value="#{userDataBean.status}">
<f:selectItem itemValue="ALL" itemLabel="All" />
<f:selectItem itemValue="A" itemLabel="Active" />
<f:selectItem itemValue="IA" itemLabel="Inactive" />
</h:selectOneMenu>
<h:commandButton value="Search" action="#{userServiceBean.searchApplicantsByCriteria()}">
<f:ajax execute="searchApplicant" render=":myForm001:appListDataTable"/>
</h:commandButton>
</div>
</h:form>
<hr width="100%"></hr>
<br />
<center>
<h:form id="myForm001" prependId="false">
<f:metadata>
<f:event listener="#{userServiceBean.showTop10Applicant()}" type="preRenderView" />
</f:metadata>
<h:dataTable var="c" value="#{userServiceBean.showTop10Applicant()}"
styleClass="order-table"
headerClass="order-table-header"
rowClasses="order-table-odd-row,order-table-even-row"
border="1" id="appListDataTable" width="100%">
<h:column>
<f:facet name="header">
Applicant Name
</f:facet>
#{c.displayName}
</h:column>
<h:column>
<f:facet name="header">
User ID
</f:facet>
#{c.userId}
</h:column>
<h:column>
<f:facet name="header">
Email ID
</f:facet>
#{c.email}
</h:column>
<h:column>
<f:facet name="header">
Mobile Number
</f:facet>
#{c.contactReference}
</h:column>
<h:column>
<f:facet name="header">
Active?
</f:facet>
<h:selectBooleanCheckbox value="#{c.isActive}"></h:selectBooleanCheckbox>
</h:column>
</h:dataTable>
<br />
</h:form>
</center>
</ui:define>
</ui:composition>
</h:body>
</html>

You need to wrap the datatable in a panelGroup like <h:panelGroup id="dataTableGroup"> and then call <f:ajax execute="searchApplicant" render="dataTableGroup"/>. This should work.

You are updating the wrong component. The ":" is the document root and you certainly have a form tag wrapped around your dataTable (that's why I asked for the form). So at least you should use something like this:
render=":formId:appListDataTable"
Replace formId with your real form id. This assumes that there are no other naming containers in between like h:panelGroup etc.
If both (the input field and the table) are inside the same naming container you could omit the colon:
render="appListDataTable"
Furthermore there might be other sources of error. I would suspect your backing bean methods (as commented by Daniel, that's why I asked for the bean code).

Related

f:ajax doesn't render DataTable with a value choosen from selectOneMenu [duplicate]

This question already has answers here:
commandButton/commandLink/ajax action/listener method not invoked or input value not set/updated
(12 answers)
Closed 4 years ago.
I'm trying to use a <f:selectOneMenu> to show a dataTable based on the previously chosen value. The DataTable doesn't be rendered, I tried also <f:ajax render="tabella"> or without the panelGroup or specifying event or excecute but it didn't works. I don't know how to solve it. Here is the code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://java.sun.com/jsf/core">
<ui:composition template="/template.xhtml">
<ui:define name="content">
<h:form id="form1">
<h:panelGroup id="pannello" >
<h:selectOneMenu id="marcaScelta" value="#{marcaController.marca}" >
<f:selectItem itemLabel="Scegli una marca"/>
<f:selectItems value="#{marcaController.listaMarche()}" var="m" itemLabel="#{m.nome}" itemValue="#{m.nome}">
</f:selectItems>
<f:ajax render="pannello form1" />
</h:selectOneMenu>
<h1 align="center"> Elenco prodotti #{marcaController.marca.nome} </h1>
<h:dataTable id="tabella" value="#{marcaController.marca.prodotti}" var="prodotto">
<h:column>
<f:facet name="header">
<h:outputText value="Nome" />
</f:facet>
<h:outputText value="#{prodotto.nome}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Prezzo" />
</f:facet>
<h:outputText value="#{prodotto.prezzo}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Quantita" />
</f:facet>
<h:outputText value="#{prodotto.quantita}" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Azioni" />
</f:facet>
<h:commandLink action="#{carrelloController.aggiungiAlCarrello(prodotto)}" value="Aggiungi al Carrello"></h:commandLink>
</h:column>
</h:dataTable>
</h:panelGroup>
</h:form>
</ui:define>
</ui:composition>
</html>
I think that the listner is not added. So you can do:
Add a new method to marcaController, for example 'public void doChangeXX()'
Replace
< f:ajax render="pannello form1" />
With
<f:ajax listener="#{marcaController.doChangeXX}" render="pannello form1" />
Hope this help.

Why does JSF/AJAX skip phases?

I have page with an initial search/h:datatable on top. It renders well and displays all the text units (tokens) which are available.
Leading each row of the search results with a button "view". This button rerenders the panel group textUnitGroup, which holds the details of this token. Now, that works just fine. I can click all the token's view button and the area is refreshed WITHOUT a page reload. With the input fields of that panel group (form in embeded) I can also persist new tokens. Works, too.
However, if I load token details into that detail form (form is rendered again), and I press the "save text" button, JSF phase 2, 3, 4 and 5 are skipped (which did not happen, when I save a new token and the "view" button has NOT been clicked before).
12:31:44,174 INFO [org.exadel.helper] (default task-22) L:54 BEFORE RESTORE_VIEW 1
12:31:44,180 INFO [org.exadel.helper] (default task-22) L:67 AFTER RESTORE_VIEW 1
12:31:44,181 INFO [org.exadel.helper] (default task-22) L:54 BEFORE RENDER_RESPONSE 6
12:31:44,257 INFO [org.exadel.helper] (default task-22) L:67 AFTER RENDER_RESPONSE 6
Somewhat changes when re-rendering the details form resp. panel group. But I don't understand why. There is NO error in the log. But it is certainly the cause of the JSF phase-skipping (otherwise the insertion of a new token would not work, too).
This is the xhtml file. Let me know if you need more.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:mywidgets="http://java.sun.com/jsf/composite/widgets"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:pt="http://xmlns.jcp.org/jsf/passthrough">
<ui:composition template="/templates/overviewTemplate.xhtml">
<!-- <ui:composition template="/templates/contentTemplate.xhtml"> -->
<ui:define name="title">Text Administration</ui:define>
<ui:define name="body">
<h1>Text Administration</h1>
<h:panelGroup layout="block" id="searchListGroup" rendered="true">
<h:form id="listOfTextUnits">
<h:inputText autocomplete="true" style="width: 300px"
value="#{textController.searchFilter}"
pt:placeholder="Token or text in English" pt:autofocus="true"
title="Search by token or text in English">
<f:ajax event="keyup" execute="#this" render="textTable" />
</h:inputText>
<p class="betweenSections" />
<h:dataTable id="textTable"
value="#{textController.findTextUnitsByString()}" var="textUnit"
styleClass="data-table" headerClass="table-header"
rowClasses="table-odd-row,table-even-row">
<h:column>
<!-- column header -->
<f:facet name="header">Action</f:facet>
<!-- row record -->
<h:commandButton value="view" styleClass="mini"
action="#{textController.loadTextDetail()}">
<f:param name="id" value="#{textUnit.id}" />
<f:ajax execute="#form" render="textUnitGroup" />
</h:commandButton>
</h:column>
<h:column sortBy="#{textUnit.token}"
filterExpression="#{empty filterValue or fn:startsWith(textUnit.token, filterValue)}"
filterValue="#{textController.searchFilter}">
<f:facet name="header">Token</f:facet>
<h:outputText value="#{textUnit.token}" />
</h:column>
<h:column>
<!-- column header -->
<f:facet name="header">Default Text</f:facet>
<!-- row record -->
#{textUnit.defaultText}
</h:column>
</h:dataTable>
</h:form>
</h:panelGroup>
<h:panelGroup layout="block" id="textUnitGroup"
rendered="true">
<h2>Text unit</h2>
<h:form id="textUnit">
<h:inputHidden id="id" value="#{textController.id}" />
<label for="token">Token</label>
<h:inputText id="token" value="#{textController.token}"
required="true"
requiredMessage="Please insert a token string for this new translation." />
<label for="text">Default Text</label>
<h:inputTextarea id="text" value="#{textController.text}"
required="true"
requiredMessage="Please insert a default text translation."
cols="100" />
<h:commandButton value="save text"
action="#{textController.saveText()}">
<f:ajax execute="#form" render="searchListGroup" />
</h:commandButton>
</h:form>
</h:panelGroup>
<p class="betweenSections" />
</ui:define>
</ui:composition>
</html>
Thanks for any hint
--------------------------------UPDATE-------------------------------
Assuming that something with the JavaScript code has gone broken, I did put the h:panelGroup within the h:form tags. Now that works. The drawback with this is, that the h2 tags is never rerendered erspectively shown. This is what I wanted in the next step. Hide the form and then display, when needed.
To properly rephrase the question: How could one re-render a panelgroup which contains multiple h:form whitout listing all the forms in the render attribute of the f:ajax tag? Not possible at all?
Thanks for any hint!

JSF Primefaces ajax on p:datatable

I am using JSF Primefaces for my UI. I have a specific requirement about ajax on p:datatable. This is a sample page of my project:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:comp="http://java.sun.com/jsf/composite/components/">
<ui:define name="content">
<h:form id="form1">
<p:growl id="messages" showDetail="false" />
<p:panel header="Available Rows" style="width: 15%;">
<p:dataTable id="table" value="#{rowBean.rows}" var="row"
widgetVar="50" style="width: 60px;" editable="true">
<p:ajax event="rowEdit" listener="#{rowBean.onEdit}"
update="form1:messages" />
<p:ajax event="rowEditCancel" listener="#{rowBean.onCancel}"
update=":form1:messages" />
<p:column>
<f:facet name="header">
<h:outputText value="Row ID" />
</f:facet>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{row.id}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{row.id}"
style="width:100%" label="Row ID">
</p:inputText>
</f:facet>
</p:cellEditor>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Row Value" />
</f:facet>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{row.value}" />
</f:facet>
<f:facet name="input">
<p:inputText disabled="true" value="#{row.value}"
style="width:100%" label="Row Value">
</p:inputText>
</f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:6%">
<p:rowEditor />
</p:column>
</p:dataTable>
</p:panel>
<p:spacer height="5px;"/>
<p:panel id="createPanel" header="Create Row" closable="false" toggleable="true"
collapsed="true" style="width: 15%;">
<p:panelGrid columns="6">
<h:outputLabel for="rowBean" value="Row ID" />
<p:inputText value="#{rowBean.row.id}"
required="true" label="Row ID" style="width:125px" />
<h:outputLabel for="rowBean" value="Row Value" />
<p:inputText value="#{rowBean.row.value}"
required="true" label="Row Value" style="width:125px" />
<f:facet name="footer">
<p:commandButton value="Create" action="#{rowBean.createRow}"
update=":form1" />
</f:facet>
</p:panelGrid>
</p:panel>
</h:form>
</ui:define>
</ui:composition>
Here I have a data table which lists down all the rows created. Each row is having id and value. Value is editable. There is one more panel within the form which creates new rows. Backing bean is pre-populated with all the created rows with #PostConstruct. Backing bean is having other methods to edit, cancel and create. This page is working and given below is the new requirement.
In some cases there can be an error associated with each row. If there is an error attached with a row, then the value text needs to be updated like a link. While clicking on the link, the row ID and a parameter needs to be passed to backing bean. With these params, backing bean fetches the error details and passes it to the page. Then the error message needs to be shown on a pop-up.
Can you tell me how to do this?
On the XHTML side:
<p:messages id="messages" showDetail="true" autoUpdate="true" closable="true" />
On the JAVA side, in the function you call when you press the button:
if(error) {
FacesContext.getCurrentInstance().addMessage(
null,
new FacesMessage(FacesMessage.SEVERITY_WARN, "Error",
"Your error message."));
}
PD: This is my first answer, i'm getting used to the post options, i'm sorry if you dont see my message properly ;)
Maybe like this?:
<f:facet name="output">
<h:outputText value="#{row.value}" rendered="#{!row.hasError}" />
<h:commandLink value="#{row.value}" rendered="#{row.hasError}" command="#{row.command(parameters..)}" />
</f:facet>

Richfaces 4.4 ExtendedDataTable spam Ajax requests after scroll down

The problem is when i use global status for ajax requests and ExtendedDataTable together strange bug happens - when i scroll down (i have large data loaded in the table) ajax request keep spaming in the console and the ajax status (picture loading) keep flashing.
there is my code:
<h:head></h:head>
<h:body>
<h:outputText value="TEsts with Extended Table" />
<h:form id="form">
<a4j:status id="waithStatus"
onstart="#{rich:component('waithStatusPanel')}.show();"
onstop="#{rich:component('waithStatusPanel')}.hide();">
<f:facet name="start">
<rich:popupPanel id="waithStatusPanel" autosized="true">
<h:graphicImage library="images" name="waith.gif" />
</rich:popupPanel>
</f:facet>
</a4j:status>
<h:panelGrid columns="2">
<rich:extendedDataTable value="#{testKrasi.tableList}" var="row" id="table"
selectionMode="none" clientRows="10" style="height:250px;width:400px"
iterationStatusVar="it">
<rich:column>
<f:facet name="header">#</f:facet>
#{it.index}
</rich:column>
<rich:column filter="#{testKrasi.vendorFilter}" filterType="custom">
<f:facet name="header">
vendor
</f:facet>
<h:outputText value="#{row[1]}"/>
</rich:column>
<rich:column filter="#{testKrasi.modelFilter}" filterType="custom">
<f:facet name="header">
model
</f:facet>
<h:outputText value="#{row[2]}"/>
</rich:column>
</rich:extendedDataTable>
</h:panelGrid>
</h:form>
</h:body>
</html>
and there is screenshot of the firebug console
the AJAX response is
<partial-response>
<changes>
<update id="javax.faces.ViewState">-2313795786913874202:5967295793801101249</update>
</changes>
</partial-response>
I don't know what to do... i try to fix this problem over a week now...
Please help me.
As you are using ajax lazy data loading for the table, these data load requests cause status to show.
You need either disable ajax data loading if you don't need that (refer to RichFaces Showcase to know how).
Or to disable status to show on the table updates. You can wrap the table into a4j:region to do this.

h:selectOneMenu default value issue when put it in h:dataTable

I have a problem with h:selectOneMenu.
If I put it in h:dataTable I'm unable to set the default value.
This is the code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<ui:component xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<h:dataTable value="#{utenteBean.listaUtenti}"
var="utente" >
<h:column>
<f:facet name="header">
<h:outputText value="#" />
</f:facet>
<h:outputText value="1"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{sW.headerUsername}" />
</f:facet>
<h:outputText escape="false"
value="#{utente.username}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{sW.headerEnabled}" />
</f:facet>
<h:form>
<h:commandLink action="#{utenteBean.updateAbilitato}">
<h:outputText value="#{utente.enabled}">
<f:converter converterId="abilitatoConverter"/>
</h:outputText>
<f:setPropertyActionListener target="#{utenteBean.utente}"
value="#{utente}"/>
</h:commandLink>
</h:form>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{sW.headerRuolo}" />
</f:facet>
<h:form>
<h:selectOneMenu value="ROLE_ADMIN"
valueChangeListener="#{utenteBean.updateRuolo}">
<f:selectItem itemLabel="Utente" itemValue="ROLE_USER"/>
<f:selectItem itemLabel="Admin" itemValue="ROLE_ADMIN"/>
</h:selectOneMenu>
</h:form>
</h:panelGroup>
</h:column>
</h:dataTable>
</ui:component>
If I move the h:form with selectOneMenu out of h:dataTable all works.
I'm using jsf2.0 on glassfish3
Any Ideas?
(Solved by the OP in a question edit. Converted to a community wiki answer. See Question with no answers, but issue solved in the comments (or extended in chat) )
The OP wrote:
I have solved it by myself, i think there is a bug in <h:selectOneMenu value="ROLE_ADMIN" i changed the value="" from static to dynamic with a reference to an istance in managed bean and all work perfectly.

Resources