How to re-render <ui:repeat> using <f:ajax render> - ajax

I have implemented a list created by a repeater:
<ui:repeat value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
and a Button that filters my list:
<h:commandLink action="#{overviewController.filterNew}">
<h:outputText value="Filter List" />
</h:commandLink>
So, is there an easy way to render only my repeater after clicking the command link (with AJAX) :-)
I tried following:
<f:ajax render="repeater">
ui:repeat id="repeater" value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
<f:ajax />
<h:commandLink action="#{overviewController.filterNew}">
<h:outputText value="Filter List" />
<f:ajax event="click" render="repeater"/>
</h:commandLink>
but that did not work..
Update
<h:form>
ui:repeat id="repeater" value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
<h:commandLink action="#{overviewController.filterNew}">
<h:outputText value="Filter List" />
<f:ajax event="click" render="repeater"/>
</h:commandLink>
</h:form>
doesn't work either... Maybe I hav to put the action method (overviewController.filterNew) into the ajax tag?
Update 2
<f:ajax event="click" render="repeater">
<h:commandLink action="#{overviewController.filterEBus}">
<h:outputText value="EBusiness" />
</h:commandLink>
</f:ajax>
Doesn't work either!
Maybe it's not possible to rerender a repeater ? is there another element like a div tag or something that can be rerendered???
...
Thank you for your help

The <ui:repeat> itself does not generate any HTML to the output. The <f:ajax render> expects an ID which is present in the HTML DOM tree. Put it in a <h:panelGroup> with an id and reference it instead.
<h:form>
<h:panelGroup id="projects">
<ui:repeat value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
</h:panelGroup>
<h:commandLink action="#{overviewController.filterNew}">
<h:outputText value="Filter List" />
<f:ajax execute="#form" render="projects" />
</h:commandLink>
</h:form>

Yes:
using Richfaces <a4j:commandButton reRender="targetId" />
using JSF 2.0 <f:ajax event="click" render="targetId">
using Primefaces <p:ajax>

<f:ajax render="repeater">
ui:repeat id="repeater" value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
<f:ajax />
why did you wrap it with f:ajax? It's redundant in this case.
Make sure that your components are surrounded by <h:form> tag
<h:form>
<ui:repeat id="repeater" value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
<h:commandLink action="#{overviewController.filterNew}">
<h:outputText value="Filter List" />
<f:ajax event="click" render="repeater"/>
</h:commandLink>
</h:form>

How about this:
<ui:repeat id="repeater" value="#{projectData.paginator.list}" var="project">
<h:outputText value="#{project.title}" />
</ui:repeat>
<h:commandLink>
<h:outputText value="Filter List" />
<f:ajax render="repeater" listener="#{overviewController.filterNew}" />
</h:commandLink>

Related

Values repeated in jsf <ui:repeat>

I have repeated values on my form. I am using <ui:repeat> tag.
My code:
<h:panelGroup id="alvs">
<ui:repeat value="#{encuestaController.newEncuesta.preguntas}" var="preg">
<h:outputLabel for="preg" value="add question:" style="font-weight:blue" />
<p:inputText id="preg" value="#{preg.pregunta}" />
<h:outputLabel for="value2" value="The question is option:" style="font-weight:bold" />
<p:selectBooleanButton id="value2" value="#{preg.opcional}" onLabel="Si" offLabel="No" onIcon="ui-icon-check" offIcon="ui-icon-close" style="width:60px">
<p:ajax update="f1:growl2"/>
</p:selectBooleanButton>
<h3 style="margin-top:2px">Question Type</h3>
<p:selectOneMenu value="#{preg.tipo}">
<f:selectItem itemValue="1" itemLabel="one option" />
<f:selectItem itemValue="2" itemLabel="many option" />
</p:selectOneMenu>
<h:panelGroup id="aux">
<ui:repeat value="#{preguntaController.newPregunta.opciones}" var="opc">
<h:panelGroup id="pn11" rendered="#{preg.tipo eq 1}">
uno<p:inputText value="#{opc.descripcion}"/>
</h:panelGroup>
<h:panelGroup id="pn12" rendered="#{preg.tipo eq 2}" >
dos<p:inputText value="#{opc.descripcion}"/>
</h:panelGroup>
</ui:repeat>
</h:panelGroup>
</ui:repeat>
</h:panelGroup>
<p:commandButton class="btn-floating btn-large waves-effect waves-light red" actionListener="#{preguntaController.addOcion}" update="f1:growl2" value="Add" >
<f:ajax execute="pn11 pn12" render="alvs" />
</p:commandButton>
The problem is when I want to add a new option(opciones) in the question(pregunta) with <p:commandButton/>
This adds the same options for the previous question as for the new one.
Maybe, the error is ajax? <f:ajax execute="pn11 pn12" render="alvs" />
Help me!!!
Image Description
As i see it, the problem is regarding the fact that you are producing multiple options using the ui:repeat, but you are declaring the same id for each of the panelGroups inside.
Add some custom prefix or sufix to each of the ids based on some unique value from the var="opt" (like an id):
<ui:repeat value="#{preguntaController.newPregunta.opciones}" var="opc">
<h:panelGroup id="pn11#{opc.id}" rendered="#{preg.tipo eq 1}">
uno<p:inputText value="#{opc.descripcion}"/>
</h:panelGroup>
<h:panelGroup id="pn12#{opc.id}" rendered="#{preg.tipo eq 2}" >
dos<p:inputText value="#{opc.descripcion}"/>
</h:panelGroup>
</ui:repeat>
Otherwise you will keep overriding the previous panelGroup's.
Also you would need to use a broader scope of execution for your ajax request.
I would use the first panelGroup outside of the ui:repeat:
<f:ajax execute="aux" render="alvs" />

Updating Primefaces datatable summary row using Ajax

How can I update a primefaces datatable summary row after submitting a form (dialog)?
The datatable is already updated correctly after some CRUD operation, but the summary row doesn't. I'm using p:remoteCommand to update the summary row when filtering the datatable and it works fine.
The List.xhtml:
<h:form id="TreinamentosListForm">
<p:panel header="#{treinaBundle.ListTreinamentosTitle}" >
<p:remoteCommand name="updateFooterSumCountId" update="datalist:footerSumCountId" />
<p:dataTable id="datalist"
filteredValue="#{treinamentosController.filteredTreinamentos}"
value="#{treinamentosController.items}"
var="item"
rowKey="#{item.id}"
paginator="true"
selectionMode="single"
selection="#{treinamentosController.selected}">
<p:ajax event="filter" process="#form" update="#this" listener="#{treinamentosController.onFilter}" oncomplete="updateFooterSumCountId()" />
<p:ajax event="rowSelect" update=":TreinamentosListForm:createButton :TreinamentosListForm:viewButton :TreinamentosListForm:editButton :TreinamentosListForm:deleteButton :TreinamentosListForm:TreinamentosDataTableContextMenu" listener="#{treinamentosController.resetParents}"/>
<p:ajax event="rowUnselect" update=":TreinamentosListForm:createButton :TreinamentosListForm:viewButton :TreinamentosListForm:editButton :TreinamentosListForm:deleteButton :TreinamentosListForm:TreinamentosDataTableContextMenu" listener="#{treinamentosController.resetParents}"/>
<p:ajax event="rowDblselect" onsuccess="document.getElementById('TreinamentosListForm:viewButton').click();"/>
<p:column sortBy="#{item.id}" filterBy="#{item.id}" style="text-align: right">
<f:facet name="header">
<h:outputText value="#{treinaBundle.ListTreinamentosTitle_id}"/>
</f:facet>
<h:outputText value="#{item.id}"/>
</p:column>
<p:columnGroup id="totalGroup" rendered="true" type="footer" >
<p:row>
<p:column style="text-align:right">
<f:facet name="footer">
<!-- the summary row: -->
<h:outputText id="footerSumCountId" value="#{treinamentosController.sumCountId}" />
</f:facet>
</p:column>
</p:row>
</p:columnGroup>
</p:dataTable>
<f:facet name="header">
<p:commandButton id="createButton" icon="ui-icon-plus" value="#{treinaBundle.Create}" actionListener="#{treinamentosController.prepareCreate}" update=":TreinamentosCreateForm" oncomplete="PF('TreinamentosCreateDialog').show()"/>
<p:commandButton id="viewButton" icon="ui-icon-search" value="#{treinaBundle.View}" update=":TreinamentosViewForm" oncomplete="PF('TreinamentosViewDialog').show()" disabled="#{empty treinamentosController.selected}"/>
<p:commandButton id="editButton" icon="ui-icon-pencil" value="#{treinaBundle.Edit}" update=":TreinamentosEditForm" oncomplete="PF('TreinamentosEditDialog').show()" disabled="#{empty treinamentosController.selected}"/>
<p:commandButton id="deleteButton" icon="ui-icon-trash" value="#{treinaBundle.Delete}" actionListener="#{treinamentosController.delete}" update=":growl,datalist" disabled="#{empty treinamentosController.selected}">
<p:confirm header="#{treinaBundle.ConfirmationHeader}" message="#{treinaBundle.ConfirmDeleteMessage}" icon="ui-icon-alert"/>
</p:commandButton>
</f:facet>
</p:panel>
<ui:include src="/WEB-INF/include/confirmation.xhtml"/>
</h:form>
The Create.xhtml:
<p:dialog id="TreinamentosCreateDlg" widgetVar="TreinamentosCreateDialog" modal="true" resizable="false" appendTo="#(body)" header="#{treinaBundle.CreateTreinamentosTitle}" closeOnEscape="true" >
<h:form id="TreinamentosCreateForm">
<h:panelGroup id="display" rendered="#{treinamentosController.selected != null}">
<p:panelGrid columns="2" columnClasses="column">
<p:outputLabel value="#{treinaBundle.CreateTreinamentosLabel_id}" for="id" />
<p:outputLabel id="id" value="Value automatically generated from database." title="#{treinaBundle.CreateTreinamentosTitle_id}" />
</p:panelGrid>
<p:commandButton actionListener="#{treinamentosController.saveNew}" value="#{treinaBundle.Save}" update="#all,display,:TreinamentosListForm:datalist,:growl" oncomplete="handleSubmit(xhr,status,args,PF('TreinamentosCreateDialog'));">
<p:confirm header="#{treinaBundle.ConfirmationHeader}" message="#{treinaBundle.ConfirmCreateMessage}" icon="ui-icon-alert"/>
</p:commandButton>
<p:commandButton value="#{treinaBundle.Cancel}" onclick="PF('TreinamentosCreateDialog').hide()"/>
</h:panelGroup>
</h:form>
</p:dialog>
Thanks in advance.
After reading the Primefaces 5 documentation, what I did was to invoke (in the Create.xhtml) the Primefaces filter method, referencing through the widgetVar defined in the target datatable (in List.xhtml). Doing so, it triggers my p:remoteCommand, which in its turn, triggers the update for the summary row:
<p:commandButton actionListener="#{treinamentosController.saveNew}" value="#{treinaBundle.Save}" update="#this,display,:TreinamentosListForm:datalist,:growl" oncomplete="handleSubmit(xhr,status,args,PF('TreinamentosCreateDialog'),PF('treinamentosTable').filter());" >
<p:confirm header="#{treinaBundle.ConfirmationHeader}" message="#{treinaBundle.ConfirmCreateMessage}" icon="ui-icon-alert"/>
</p:commandButton>
If someone has a more elegant solution, please share. I had not time

JSF Ajax not submitting

I have the following JSF code in my page
<h:panelGroup id="rSelectionPanel" rendered="#{bean.admin}">
<h4 class="header-line">Admin Panel</h4>
<h:panelGroup rendered="#{bean.selectionMode=='RS'}">
<h:form styleClass="registerForm">
<h:outputLabel value="End Line1?" rendered="#{not bean.endLine2}"></h:outputLabel>
<h:selectBooleanCheckbox id="endLine1" value="#{bean.endLine1}" rendered="#{not bean.endLine2}">
<p:ajax event="change" update=":rSelectionPanel"></p:ajax>
</h:selectBooleanCheckbox>
<h:outputLabel value="End Line2?" rendered="#{not bean.endLine1}"/>
<h:selectBooleanCheckbox id="endLine2" value="#{bean.endLine2}" rendered="#{not bean.endLine1}">
<p:ajax event="change" update=":rSelectionPanel"></p:ajax>
</h:selectBooleanCheckbox>
<h:inputTextarea id="newLine2Name" styleClass="form-poshytip" title="Line2 Name" rows="1" maxlength="50"
value="#{bean.newLine2Name}" validatorMessage="Too many characters" rendered="#{bean.endLine2}">
<f:passThroughAttribute name="placeholder" value="Line2 Name" />
<f:validateLength maximum="50" />
</h:inputTextarea>
<h:commandButton styleClass="submit" value="Select Line" action="#{bean.confirmLineBy}">
</h:commandButton>
</h:form>
</h:panelGroup>
</h:panelGroup>
With the following backing bean java code
public void confirmLineBy(){
getLog().debug("Entering confirmLineBy....");
ConfirmLineByRequest request = new ConfirmLineByRequest();
request.setPage(getPage());
request.setEndLine1(endLine1);
if(isEndLine2())request.setNewLine2Name(newLine2Name);
request.setEndLine2(isEndLine2());
ConfirmLineByResponse response = LineService.confirmLineBy(request, null);
nextUnconfirmedLines.removeAll(nextUnconfirmedLines);
setConfirmedLines(response.getConfirmedLines());
setLine2s();
setAddedLine(false);
getLog().debug("CONFIRMED LINES SIZE: "+confirmedLines.size());
getLog().debug("Exiting confirmLineBy....");
}
When clicking the commandButton with neither of the boxes checked, it submits fine. But when checking either of the checkboxes, it doesn't even call bean.confirmLineBy().
Any ideas?
Changed from using to . sorted now.

PrimeFaces dataTable doesn''t render when exists binding attribute

I'm creating a dataTable with two dataTable inside :).
But this time I'm having problem to render it when I try use binding attribute in a h:panelGroup that wraps first dataTable.
I'm using binding to help refresh just the panelGroup, like BalusC told in this question. When I remove the binding attribute the dataTable renders normally, but of course nothing is rendered with f:ajax tags inside the dataTables.
Here is the xhtml:
<ui:component>
<h:panelGroup>
<h:panelGroup layout="block;" id="#{id}"
binding="#{painelTabelaContatos}" rendered="true">
<p:dataTable id="tabela#{id}"
value="#{modeloTabelaContatos.listaDeContatos}" var="contato"
selectionMode="single"
rowSelectListener="#{controladorTabelaContatos.processarSelecaoLinha}"
rowUnselectListener="#{controladorTabelaContatos.processarDeselecaoLinha}"
selection="#{modeloTabelaContatos.contatoSelecionado}">
<p:column headerText="Contatos">
<hrgi:editableText style="width:100%" value="#{contato.descricao}" />
</p:column>
<p:column headerText="Telefones">
<h:dataTable value="#{contato.telefones}" var="telefone">
<h:column>
<h:inputText value="#{telefone}" />
</h:column>
<h:column>
<h:graphicImage library="img" name="default_trash.png"
style="cursor:pointer;">
<f:ajax event="click" render=":#{painelTabelaContatos.clientId}"
listener="#{controladorTabelaContatos.removerTelefone(contato, telefone)}" />
</h:graphicImage>
</h:column>
</h:dataTable>
</p:column>
<p:column headerText="e-mails">
<h:dataTable value="#{contato.emails}" var="email">
<h:column>
<h:inputText value="#{email}" />
</h:column>
<h:column>
<h:graphicImage library="img" name="default_trash.png"
style="cursor:pointer;">
<f:ajax event="click" render=":#{painelTabelaContatos.clientId}"
listener="#{controladorTabelaContatos.removerEmail(contato, email)}" />
</h:graphicImage>
</h:column>
</h:dataTable>
</p:column>
<p:column>
<h:graphicImage library="img" name="default_trash.png"
style="cursor:pointer;">
<f:ajax render=":#{painelTabelaContatos.clientId}" event="click"
listener="#{controladorTabelaContatos.removerContato(contato)}" />
</h:graphicImage>
</p:column>
</p:dataTable>
</h:panelGroup>
<h:panelGroup layout="block">
<p:commandButton value="ADICIONAR CONTATO" update="#{id}"
immediate="true"
action="#{controladorTabelaContatos.adicionarContato}" />
<p:commandButton value="ADICIONAR TELEFONE" update="#{id}"
immediate="true"
action="#{controladorTabelaContatos.adicionarTelefone}" />
<p:commandButton value="ADICIONAR E-MAIL" update="#{id}"
immediate="true"
action="#{controladorTabelaContatos.adicionarEmail}" />
</h:panelGroup>
</h:panelGroup>
</ui:component>
I've already tried remove the h:dataTables that are inside p:dataTable, but without success.
This component is just the content of a PrimeFaces tab, and this tab is inside a PrimeFaces dialog. Could someone explain me why is this happening??
I've found the cause of error, after it was easy find a solution...
The problem is caused because I call this component in two different pages:
popupCadastroPessoa.xhtml
<ui:include src="../tabs/abaEdicaoContatos.xhtml">
<ui:param name="id" value="painelContatoPessoa" />
</ui:include>
and in popupCadastroFuncionario.xhtml
<ui:include src="../tabs/abaEdicaoContatos.xhtml">
<ui:param name="id" value="painelContatoFuncionario" />
</ui:include>
cause I didn't really created the binding bean, JSF gets confused. So I've just created two UIPanel beans and passed it as parameter:
<ui:include src="../tabs/abaEdicaoContatos.xhtml">
<ui:param name="id" value="painelContatoPessoa" />
<ui:param name="painelTabelaContatos" value="#{bindingTabelaContatoPessoa}"/>
</ui:include>
Was my fault. Thanks for your attention and sorry for the inconvenience.

richfaces data-table error

I am new to richfaces.
I have a problem with rich:datatable filtering, the source code of my page is like the site example:
<h:form id="form">
<rich:dataTable keepSaved="true" id="richTable" var="record" value="#{citiesBean}" rows="20">
<rich:column >
<f:facet name="header">
<h:commandLink action="#{bean.toggleSort}">
#{bean.sortOrders['cityTitle']}
<a4j:ajax render="richTable" />
<f:setPropertyActionListener target="#{bean.sortProperty}" value="#{'cityTitle'}" />
</h:commandLink>
<br />
<h:inputText value="#{citiesBean.filterValues['cityTitle']}">
<a4j:ajax render="richTable#body scroller" event="keyup" />
</h:inputText>
</f:facet>
<h:outputText value="#{record['cityTitle']}" />
</rich:column>
<rich:column >
<f:facet name="header">
<h:commandLink action="#{bean.toggleSort}">
#{bean.sortOrders['cityCode']}
<a4j:ajax render="richTable" />
<f:setPropertyActionListener target="#{bean.sortProperty}" value="#{'cityCode'}" />
</h:commandLink>
<br />
<h:inputText value="#{citiesBean.filterValues['cityCode']}">
<a4j:ajax render="richTable#body scroller" event="keyup" />
</h:inputText>
</f:facet>
<h:outputText value="#{record['cityCode']}" />
</rich:column>
<f:facet name="footer">
<rich:dataScroller id="scroller" />
</f:facet>
</rich:dataTable>
</h:form>
everything seems OK but it has some problems.
1- datascroller does not work without render attribute set to 'richTable' but it works on demo!!!
2-when i type something on filter input, the table does not get updated!, i have checked the request and response on firebug,
the response does not have a valid id, i mean it look like this:
<update id="form:richTable:tb"><tbody id="form:richTable:0:tb" ....
what is wrong with my codes?!
I am using, richfaces 4, Glassfish 3.1, Firefox 3.6
thanks in advance.
I think it was a kind of bug. Now it is fine with version 4.1 M1.

Resources