Values repeated in jsf <ui:repeat> - ajax

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" />

Related

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.

Ajax not rendering new data for <h:selectOneMenu>

I am trying to update a selectOneMenu from the results of another selectOneMenu.
When group is selected the user menu should be updated.
I have verified that the data for the user menu is being updated. It is not being rendered however.
Currently running Primefaces 3.4.2 and JSF 2.1
<ui:composition>
<br/><br/>
<h:form id="transferForm">
<h:panelGrid columns="1" style="width: 500px;margin: auto;text-align: center" >
<h:panelGroup>
<h:outputLabel for="group" value="Group" />
<h:selectOneMenu id="group" value="#{projectBean.transferUtil.selectedTransferGroup}" >
<f:selectItems value="#{projectBean.transferUtil.transferGroups}" />
<f:ajax execute="group" render="user" />
</h:selectOneMenu>
<br />
<h:outputLabel for="user" value="User" />
<h:selectOneMenu id="user" value="#{projectBean.transferUtil.selectedTransferUser}" required="true" requiredMessage="Select User" >
<f:selectItems value="#{projectBean.transferUtil.transferUsers}" />
</h:selectOneMenu>
</h:panelGroup>
<p:commandButton id="projectTransferButton" action="#{projectBean.transferUtil.transfer}" value="Transfer" update=":projtabs,:growlForm:growlMesg">
<f:setPropertyActionListener target="#{projectBean.activeTab}" value="#{projectBean.project_tab_index}" />
</p:commandButton>
</h:panelGrid>
</h:form>
<br/><br/>
[EDIT]
Alright this is the error I am getting.
<?xml version='1.0' encoding='UTF-8'?>
<partial-response><error><error-name>class java.lang.IllegalArgumentException</error-name><error-message><![CDATA[rss02.1 OPERA]]></error-message></error></partial-response>
And this is the code in question.
<p:dataGrid var="area" value="#{projectBean.projectUtil.project.rssAreas}" columns="1">
<p:column>
<h:selectBooleanCheckbox id="rss#{area.shortName}" label="#{area.name}" value="#{area.active}" />
<h:outputText value="#{area.name}" />
</p:column>
</p:dataGrid>
You should not perform business logic in getters/setters. They are invoked multiple times in JSF lifecycle and are intented to get and set the property. You should perform business logic in action(listener) methods instead.
The following construct should work:
<h:selectOneMenu id="group" value="#{projectBean.transferUtil.selectedTransferGroup}" >
<f:selectItems value="#{projectBean.transferUtil.transferGroups}" />
<f:ajax execute="group" listener="#{projectBean.transferGroupChanged}" render="user" />
</h:selectOneMenu>
<h:selectOneMenu id="user" value="#{projectBean.transferUtil.selectedTransferUser}" required="true" requiredMessage="Select User" >
<f:selectItems value="#{projectBean.transferUtil.transferUsers}" />
</h:selectOneMenu>
With
public void transferGroupChanged(AjaxBehaviorEvent event) {
// Change the transferUsers here.
}
The getters and setters should not contain any business logic. They should merely get and set the property.
See also:
Why JSF calls getters multiple times
How to load and display dependent h:selectOneMenu on change of a h:selectOneMenu

How to trigger an ajax event listener on click of p:graphicImage?

I want to do some processing when the user click on the p:graphicsImage inside a ui:repeat
How do i do it.
<ui:repeat id="repeat" value="#{getData.image}" var="imageLst" varStatus="loop">
<h:panelGroup>
<p:graphicImage id="gi1" value="#{imageStreamer.image}" alt="image not available" >
<f:param name="id" value="#{imageLst.imageID}" />
<p:ajax id="aj2" event="click" listener="#{getData.searchID}" immediate="true" update=":form:tabView:check :form:growl"/>
</p:graphicImage>
</h:panelGroup>
</ui:repeat>
In the above code if i place the ajax part doesn't get triggered.
How do i monitor a Click on the 'p:graphicImage'
The <p:graphicImage> doesn't support any ajax events.
Just wrap it in a <h:commandLink> (or the p: one).
<h:commandLink>
<p:graphicImage id="gi1" value="#{imageStreamer.image}" alt="image not available" >
<f:param name="id" value="#{imageLst.imageID}" />
</p:graphicImage>
<p:ajax id="aj2" listener="#{getData.searchID}" update=":form:tabView:check :form:growl"/>
</h:commandLink>

Fields are cleared when update p:tabView

I have a popup with three tabs in primefaces tabPanel. In the middle is a table called "composicao", this tab is rendered when user marks checkbox that is located in first tab.
The tables have a lot of inputs, selects and checkboxes that user can fill in any order, so if the user fill all fields and then mark the checkbox, all fields are cleared cause that checkbox update the tabView. I tryied set some fields immediate attribute to true and set p:ajax process attribute to #all, but with this approach nothing happens.
This is the code of tabPanel:
<h:panelGroup id="abasCadastroProduto">
<p:tabView>
<p:tab title="base">
<ui:include src="../../tabs/abaEdicaoBaseProduto.xhtml"/>
</p:tab>
<p:tab id="abaComposicao" title="composicao" rendered="#{produto.composto}">
<ui:include src="../../tabs/abaEdicaoComposicaoProduto.xhtml"/>
</p:tab>
<p:tab
title="tributacao">
<ui:include src="../../tabs/abaEdicaoTributacaoProduto.xhtml"/>
</p:tab>
</p:tabView>
</h:panelGroup>
this is part of the code of first tab:
<h:panelGroup layout="block">
<p:fieldset legend="geral">
<h:panelGroup layout="block">
<h:selectBooleanCheckbox id="produtoAtivoCheck"
value="#{produto.ativo}"/>
<h:outputLabel value="ativo" for="produtoAtivoCheck"/>
<h:selectBooleanCheckbox id="produtoMovimentoCheck"
value="#{produto.movimentaEstoque}"/>
<h:outputLabel value="movimento" for="produtoMovimentoCheck"/>
<!-- THIS IS THE CHECKBOX -->
<h:selectBooleanCheckbox id="produtoCompostoCheck"
value="#{produto.composto}">
<p:ajax event="change" update="abasCadastroProduto" process="#all"/>
</h:selectBooleanCheckbox>
<h:outputLabel value="composto" for="produtoCompostoCheck" />
</h:panelGroup>
.......
<h:panelGroup layout="block">
<h:outputLabel value="descricao"/>
<p:inputText value="#{produto.descricao}" required="true" immediate="true"
requiredMessage="obrigatorio"/>
<h:outputLabel value="complemento"/>
<p:inputText value="#{produto.descricaoComplementar}"/>
</h:panelGroup>
......
</p:fieldset>
</h:panelGroup>
Is there a way I can solve this problem??
I think is unnaceptable to user see fields they spend some time to fill, been cleared when you click in a checkbox...
Solved.
The problem was validation of required fields, so I've created a REQUIRED parameter and set it to false when user clicks checkbox:
<h:selectBooleanCheckbox id="produtoCompostoCheck"
value="#{produto.composto}" styleClass="popup-produto-geral-check">
<f:param name="REQUIRED" value="false"/>
<f:ajax event="change" immediate="true" render="abasCadastroProduto" execute="#form" />
</h:selectBooleanCheckbox>
<h:selectOneMenu value="#{produto.idClasse}" immediate="true"
required="#{param['REQUIRED']}" validatorMessage="#{cadastroMsg['popup.cadastro.produto.base.classe.invalido']}"
requiredMessage="#{cadastroMsg['popup.cadastro.produto.base.classe.obrigatorio']}">
<f:selectItems value="#{selectItemClasse.itens}"/>
<f:ajax event="change" immediate="true" render="selectSubclasse"/>
</h:selectOneMenu>
and I've made submit button set "REQUIRED" parameter to true.
instead of this:
<p:ajax event="change" update="abasCadastroProduto" process="#all"/>
try this:
<p:ajax render="#form" />

JSF and ajax: listener of dynamically added component never tirggered

I have got a problem with my JSF application.
On a page there's a form where the user can dynamically add components to that very same form. When I use the ajax listener to add the component, it is updated in the view and also in the model. But when I try to remove the dynamiccaly added component by pressing an h:actionLink its ajax listener is never triggered.
This is my code:
<h:form rendered="#{schrijvenController.verslagenController.documentSelected}">
<p>
<span class="noLabel">
#{bundle.JongereJongere}:
</span>
<h:selectOneMenu id="jongereSelect" valueChangeListener="#{schrijvenController.selecteerJongere}" immediate="true"
value="#{schrijvenController.currentJongere.jongereID}"
title="--#{bundle.JongereSelect}--">
<f:selectItems value="#{jongereController.jongerenAsSelectItems}"/>
</h:selectOneMenu>
</p>
<h:panelGroup id="personen">
<ui:repeat value="#{schrijvenController.verslagenController.persoonItems}" var="persoon">
<div class="div_add_persoon">
<div class="div_add_persoon_left">
<span class="noLabel"> #{persoon.aanwezigheid}:</span>
<h:inputText value="#{persoon.searchTerm}"
onkeypress="if (event.keyCode == 13) { onchange(); return false; }">
<f:ajax event="keypress" render="persoonLijst" listener="#{persoon.getPersonenWhereNameLikeSelectItems}" />
</h:inputText>
<h:selectOneMenu id="persoonLijst" styleClass="fixedWitdhDropDown"
value="#{persoon.currentPersoon.persoon_id}"
title="--#{bundle.PersoonSelect}--">
<f:selectItems value="#{persoon.personenWhereNameLikeSelectItems}"/>
<f:ajax event="change" render="#form" listener="#{persoon.add}" />
</h:selectOneMenu>
</div>
<h:panelGroup layout="block" styleClass="div_add_persoon_right">
<ui:repeat value="#{persoon.personen}" var="persoonPersoon">
<h:panelGroup layout="block" styleClass="div_schrijvenPersoon">
<h:outputText value=" #{persoonPersoon.naam} #{persoonPersoon.voornaam} " />
<h:commandLink value="X" id="linkske">
<f:ajax event="click" render="#form" listener="#{persoon.delete}" />
</h:commandLink>
</h:panelGroup>
</ui:repeat>
</h:panelGroup>
</div>
</ui:repeat>
<div class="clear" />
This is a Prt Sc of my view:
http://i206.photobucket.com/albums/bb69/bartloterman/pscreen.jpg?t=1302028364
If one clicks on an element from the list, it's added to the right inside a div together with a commandLink with the text "x". But when I click the "x" link nothing happens (no function is being executed). It is as if the view can't find the component. I'm using Datamodels.
I've been looking all day for a solution on the web but I couldn't find one. Any help would be greatly appreciated.
I managed to solve the problem by using the following code in my view
<h:commandLink value="X">
<f:ajax render="#form" execute="#form" listener="#{persoon.delete}" />
</h:commandLink>
Seems I needed render="#form" and execute="#form"

Resources