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
Related
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" />
I've been working with PrimeFaces for less than 24 hours so maybe I'm missing the obvious.
I have two SelectOneMenu components. the second one is no rendered at first. When a value is changed in the first one. the listener retrieves data from db, update ManagedBean property with the data and change boolean property to show the second one. The second Menu is now rendered but no data is shown.
Here is the snippet:
<h:form prependId="false" id="notaForm">
<h:panelGrid>
<p:selectOneMenu value="#{notaBean.idCurso}"
style="width:150px" >
<f:selectItem itemLabel="Seleccione curso" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{notaBean.cursos}" var="c" itemLabel="#{c.nombre}" itemValue="#{c.idCurso}"/>
<p:ajax event="change" listener="#{notaBean.onSelectCurso}" update="alumno" />
</p:selectOneMenu>
</h:panelGrid>
<h:panelGrid id="alumno">
<p:selectOneMenu value="#{notaBean.idAlumno}" var=""
style="width:150px" rendered="#{notaBean.mostrarAlumnos}">
<f:selectItem itemLabel="Seleccione alumno" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{notaBean.alumnos}" var="a" itemLabel="#{a.nombre}" itemValue="#{a.idAlumno}"/>
<p:ajax event="change" listener="#{notaBean.onSelectAlumno}" update="nota" />
</p:selectOneMenu>
</h:panelGrid>
<h:panelGrid id="nota">
<p:outputLabel for="nota" value=""
rendered="#{notaBean.mostrarNota}" />
<p:inputText value="#{notaBean.nota}" label="nota"
rendered="#{notaBean.mostrarNota}" />
<h:commandButton action="#{notaBean.insertarNota()}" id="button"
value="Guardar nota" rendered="#{notaBean.mostrarNota}"/>
</h:panelGrid>
</h:form>
notaBean.alumnos has a size of 2 (it recovers both alumni from db), and the properties nombre and idAlumno shows correctly when I print them out in console.
I am relatively new to JSF and Primefaces. I have a page in which I have three selectOneMenu displaying the same set of values from a map. I would like to make sure that the user selects different values for the three drop downs. I have achieved this by writing a custom validator. But the validator works only if I click the submit page. I want to have an ajax call which would show an error message for drop down 2 as soon as the user selects the same value as drop down 1.Also the same case for drop down 3.Here is my code snippet:
user.xhtml
<h:outputLabel for="Question1" value="#{msg['account.question1']}"/>
<h:message styleClass="validation-error" for="Question1"/>
<h:selectOneMenu id="Question1" required="true" value="#{account.question1}" class="smallTxt">
<f:selectItems value="#{controller.questionMap}" />
<f:validator validatorId="com.validator.QuestionsValidator"></f:validator>
</h:selectOneMenu>
<h:outputLabel for="Answer1" value="#{msg['account.answer1']}"/>
<h:message styleClass="validation-error" for="Answer1"/>
<h:inputText id="Answer1" required="true" value="#{account.answer1}" />
<h:outputLabel for="Question2" value="#{msg['account.question2']}"/>
<h:message styleClass="validation-error" for="Question2"/>
<h:selectOneMenu id="Question2" required="true" value="#{account.question2}" class="smallTxt">
<f:selectItems value="#{controller.questionMap}" />
</h:selectOneMenu>
<h:outputLabel for="Answer2" value="#{msg['account.answer2']}"/>
<h:message styleClass="validation-error" for="Answer2"/>
<h:inputText id="Answer2" required="true" value="#{account.answer2}" />
<h:outputLabel for="Question3" value="#{msg['account.question3']}"/>
<h:message styleClass="validation-error" for="Question3"/>
<h:selectOneMenu id="Question3" required="true" value="#{account.question3}" class="smallTxt">
<f:selectItems value="#{controller.questionMap}" />
</h:selectOneMenu>
<h:outputLabel for="Answer3" value="#{msg['account.answer3']}"/>
<h:message styleClass="validation-error" for="Answer3"/>
<h:inputText id="Answer3" required="true" value="#{account.answer3}" />
I am using JSF 2 and Primefaces 5.2.
Thanks in advance
If you want to execute your validator on an AJAX call, you have to add <f:ajax /> to your <h:selectOneMenu>
<h:selectOneMenu id="Question1" required="true" value="#{account.question1}" class="smallTxt">
<f:selectItems value="#{controller.questionMap}" />
<f:validator validatorId="com.validator.QuestionsValidator"></f:validator>
<f:ajax />
</h:selectOneMenu>
Side question: You state, that you use Primefaces 5.2, but you use JSF standard components (<h:selectOneMenu> instead of <p:selectOneMenu>). Is that on purpose?
You can apply listener on selectonemenu.linke this:
<p:selectOneMenu id="country" value="#{dropdownView.country}" style="width:150px">
<p:ajax listener="#{dropdownView.onCountryChange}" update="city" />
<f:selectItem itemLabel="Select Country" itemValue="" noSelectionOption="true" />
<f:selectItems value="#{dropdownView.countries}" />
</p:selectOneMenu>
And then in this oncountrychange() function you will get the values of all the three select items and compare them.
I'm new to jsf, and I'm writing my first application using richfaces. I'm having trouble with the ajax tag that I use to update the associated managed bean property on server for rich:calendar components. This is the code:
<rich:panel header="Computing Options">
<h4>Time Interval</h4>
<h:panelGrid columns="4" width="100%">
<h:outputText value="From" />
<rich:calendar id="intervalFrom" value="#{scenarioEditor.intervalFrom}" popup="true" showApplyButton="true" datePattern="yyy-MM-ddTHH:mm">
<a4j:ajax execute="#this" event="change" render="outFrom" />
</rich:calendar>
<h:outputText value="To" />
<rich:calendar id="intervalTo" value="#{scenarioEditor.intervalTo}" popup="true" showApplyButton="true" datePattern="yyy-MM-ddTHH:mm">
<a4j:ajax execute="#this" event="change" render="outTo" />
</rich:calendar>
<h:outputText id="outFrom" value="From: #{scenarioEditor.intervalFrom}" />
<h:outputText id="outTo" value="To: #{scenarioEditor.intervalTo}" />
</h:panelGrid>
<h4>Algorithms</h4>
<h:panelGrid columns="2">
<h:selectBooleanCheckbox value="#{scenarioEditor.visibilityClashes}" id="clash" >
<f:ajax execute="#this"/>
</h:selectBooleanCheckbox>
<h:outputLabel value="Visibility Clashes Evaluator" for="clash" style="width:170px" />
<h:selectBooleanCheckbox value="#{scenarioEditor.xBandInterference}" id="xband" >
<f:ajax execute="#this"/>
</h:selectBooleanCheckbox>
<h:outputLabel value="X-Band Interferences Evaluator" for="xband" style="width:170px"/>
</h:panelGrid>
</rich:panel>
checkboxes works fine, but the calendars do not. Why? I`ve tried both f:ajax and a4j:ajax without luck.
To better clarify, I want that right after the user has finished entering a value into the calendar, an ajax request is made that call the setter method for the associated property. And this, for the calendar does not happen while for the checkboxes, it does.
The ajax event is failing because of T in datePattern="yyy-MM-ddTHH:mm" is not a valid date formatting pattern. If you add a <rich:messages/> component to your field, you'll see that a conversion error is occurring on each ajax request. Remove the T and you'll be fine
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.