JSF onchange event - java

I have a JSF application in which I have an combobox like this.
<script type="text/javascript" defer="defer">
<!--//--><![CDATA[//><!--
helpKey = 'APPLICATION_EDIT_DATASOURCE';
function reapplyStyles() {}
function selectT(data){
if(data.status == "begin"){
$('editForm:selectTypeButton').click();
}
}
//--><!]]>
</script>
<h:form id="editForm">
<h:inputHidden id="id" value="#{applicationObject.objectId}"/>
<h:inputHidden id="type" value="#{applicationObject.object.type}"/>
<h:inputHidden id="selectedDSForApp" value="#{applicationObject.selectedDataSourceId}"/>
<ui:param name="activityDataSource" value="#{applicationObject.selectedDataSourceBean}"/>
<a4j:outputPanel id="activityDataSourceRulesPanel">
<h:panelGrid columns="2" columnClasses="padded" rowClasses="padded">
<h:outputText value="#{msgs.transformation_rule}"/>
<h:panelGroup>
<h:selectOneMenu id="dsTransformationRule" value="#{activityDataSource.selectedTransformationRule}"
disabled="#{!sp:hasRight(facesContext, 'ManageApplication')}"
readonly="#{!sp:hasRight(facesContext, 'ManageApplication')}">
<f:selectItems value="#{activityDataSource.transformationRules}"/>
</h:selectOneMenu>
<ui:fragment rendered="#{sp:hasRight(facesContext, 'ManageRules')}" >
<input type="button" value="#{msgs.button_ellipsis}" class="ruleEditorBtn"
onclick="SailPoint.Rule.Editor.edit($('editForm:dsTransformationRule').value,
'ActivityTransformer',
$('editForm:refreshActivityDataSourceRulesButton'))" />
</ui:fragment>
</h:panelGroup>
<h:outputText value="#{msgs.correlation_rule}"/>
<h:panelGroup>
<h:selectOneMenu id="dsCorrelationRule" value="#{activityDataSource.selectedCorrelationRule}"
disabled="#{!sp:hasRight(facesContext, 'ManageApplication')}"
readonly="#{!sp:hasRight(facesContext, 'ManageApplication')}">
<f:selectItems value="#{activityDataSource.correlationRules}"/>
</h:selectOneMenu>
<ui:fragment rendered="#{sp:hasRight(facesContext, 'ManageRules')}" >
<input type="button" value="#{msgs.button_ellipsis}" class="ruleEditorBtn"
onclick="SailPoint.Rule.Editor.edit($('editForm:dsCorrelationRule').value,
'ActivityCorrelation',
$('editForm:refreshActivityDataSourceRulesButton'))" />
</ui:fragment>
</h:panelGroup>
<h:outputText value="#{msgs.activity_data_src_type}"/>
<h:panelGroup>
<a4j:outputPanel id="collectorSettings">
<h:selectOneMenu id="collectorType"
value="#{activityDataSource.object.type}"
rendered="#{empty activityDataSource.object.id}"
disabled="#{!sp:hasRight(facesContext, 'ManageApplication')}"
readonly="#{!sp:hasRight(facesContext, 'ManageApplication')}">
<!-- onchange="$('editForm:selectTypeButton').click();"> -->
<f:ajax event="change"
onevent="selectT"
execute="#this dsTransformationRule dsCorrelationRule"
render="dsTransformationRule dsCorrelationRule"
listener="#{activityDataSource.handleCollectorTypeChange}" />
<f:selectItem itemValue="" itemLabel="#{msgs.select_collector_type}"/>
<f:selectItems value="#{activityDataSource.collectorTypes}"/>
</h:selectOneMenu>
<h:selectOneMenu id="fixedCollectorType" value="#{empty activityDataSource.object.type ? 'None' : activityDataSource.object.type}"
rendered="#{not empty activityDataSource.object.id}"
disabled="true"
readonly="true">
<f:selectItem itemValue="#{empty activityDataSource.object.type ? 'None' : activityDataSource.object.type}"
itemLabel="#{empty activityDataSource.object.type ? msgs.none : activityDataSource.object.type}"/>
</h:selectOneMenu>
</a4j:outputPanel>
</h:panelGroup>
</h:panelGrid>
</a4j:outputPanel>
<a4j:outputPanel id="configSettings">
<h:messages infoClass="formInfo" warnClass="formWarn" errorClass="formError" fatalClass="formError"/>
<h:panelGroup rendered="#{not empty activityDataSource.object.collector}">
<ui:include src="#{activityDataSource.configPage}"/>
</h:panelGroup>
</a4j:outputPanel>
<h:panelGroup>
<div class="buttonRow">
<ui:fragment rendered="#{sp:hasRight(facesContext, 'ManageApplication')}">
<h:commandButton id="activityDataSourceSave" action="#{activityDataSource.saveAction}" value="#{msgs.button_save}" styleClass="primaryBtn"/>
</ui:fragment>
<h:commandButton id="activityDataSourceCancel" action="#{activityDataSource.cancelAction}" value="#{msgs.button_cancel}" styleClass="secondaryBtn"/>
</div>
</h:panelGroup>
<a4j:commandButton id="refreshActivityDataSourceRulesButton"
style="display:none"
immediate="true"
render="activityDataSourceRulesPanel"/>
<a4j:commandButton id="selectTypeButton" action="#{activityDataSource.selectType}" style="display:none"
render="configSettings, collectorSettings"
oncomplete="initializeSelectedConfigPage();"/>
</h:form>
Bean Class
public String getSelectedTransformationRule() {
if (_selectedTransformationRule == null) {
ActivityDataSourceDTO dto = getObject();
if (dto != null)
_selectedTransformationRule = dto.getTransformationRule();
}
return _selectedTransformationRule;
}
public String getSelectedCorrelationRule() {
if (_selectedCorrelationRule == null) {
ActivityDataSourceDTO dto = getObject();
if (dto != null)
_selectedCorrelationRule = dto.getCorrelationRule();
}
return _selectedCorrelationRule;
}
In the above code I have a normal onchange event & an ajax onchange event on combobox element id= collectorType.
Is there any limitation in using two change for same element in JSF.
Also how can I merge first onchange to ajax onchange.

Use onevent attribute of <f:ajax> as follows:
<h:selectOneMenu id="collectorType"
value="#{activityDataSource.object.type}"
rendered="#{empty activityDataSource.object.id}"
disabled="#{!sp:hasRight(facesContext, 'ManageApplication')}"
readonly="#{!sp:hasRight(facesContext, 'ManageApplication')}">
<f:ajax event="change"
execute="#this"
render="dsTransformationRule dsCorrelationRule"
listener="#{activityDataSource.handleCollectorTypeChange}"
onevent="$('#editForm\\:selectTypeButton').click();"/>
<f:selectItem itemValue="" itemLabel="#{msgs.select_collector_type}"/>
<f:selectItems value="#{activityDataSource.collectorTypes}"/>
</h:selectOneMenu>
also notice I've modified the selector '#editForm\\:selectTypeButton' to escape the : in your button's id.
[UPDATE]
Here's what you can do to achieve the scenario we've discussed in the comments:
First to populate both dsTransformationRule and dsCorrelationRule with _selectedTransformationRule and _selectedCorrelationRule respectively, create an initialization method for them, and call it in #PostConstruct method (check Why use #PostConstruct?), so in your bean class you would have something like this:
#PostConstuct
public void init() {
initRules();
//include another things you want to be initializaed when this page finishes constructing.
}
private void initRules() {
ActivityDataSourceDTO dto = getObject();
if (dto == null)
return;
if (_selectedTransformationRule == null)
_selectedTransformationRule = dto.getTransformationRule();
if (_selectedCorrelationRule == null)
_selectedCorrelationRule = dto.getCorrelationRule();
}
//Let the getters do no dto access, so it won't matter if they're called twice on change
public String getSelectedTransformationRule() {
return _selectedTransformationRule;
}
public String getSelectedCorrelationRule() {
return _selectedCorrelationRule;
}
Now your f:ajax can normally execute and render your select menus without fearing to access your DTO layer multiple times
<f:ajax event="change" onevent="selectT"
execute="#this dsTransformationRule dsCorrelationRule"
render="dsTransformationRule dsCorrelationRule"
listener="#{activityDataSource.handleCollectorTypeChange}" />
This way, when handleCollectorTypeChange is invoked, will have both _selectedTransformationRule and _selectedCorrelationRule populated with their last selected values.
On a side note, if you want to get the values of select menus dsTransformationRule and dsCorrelationRule in a validation or conversion phase, or directly via an event listener method that is called before the Update Model Values phase, check this answer that would help you reach the value from the component.
Hopefully this would solve your issue, or at least set you in the right direction.

Related

Filtering City by state in java - Using Array

So,
I've an ArrayList with the values of State and City, And I've to check if state are equals to some variable, lets call its "var1" and if this state are equals, I've to get the city names...
I'm creating a menu filter.
<div class="col-md-3">
<label>#{msg['state']}</label>
<h:selectOneMenu id="mdl-state" value="#{saisReportQueryBean.keyState}" class="form-control">
<f:ajax listener="#{saisReportQueryBean.Teste()}"/>
<f:selectItem itemValue="#{null}" itemLabel="#{msg['select_state']}" noSelectionOption="true" />
<f:selectItems value="#{saisReportQueryBean.keyState}" var="estado" itemValue="#{estado}" itemLabel="#{estado}" />
</h:selectOneMenu>
</div>
<div class="col-md-3">
<label>#{msg['city']}</label>
<h:selectOneMenu id="mdl-city" value="#{saisReportQueryBean.keyCity}" class="form-control">
<f:selectItem itemValue="#{null}" itemLabel="#{msg['select_city']}" noSelectionOption="true" />
<f:selectItems value="#{saisReportQueryBean.keyCity}" var="cidade" itemValue="#{cidade}" itemLabel="#{cidade}" />
</h:selectOneMenu>
</div>
When I select the state, I've to update my city itens with just only city in references with the state selected.
Here is my java code.:
protected void updateData() {
this.reportQuery = new SaisReportQuery();
this.queryExecuted = false;
cidades = cidadesIbgeBeanRemote.findAll();
cidades.sort((f1, f2) -> f1.getMunicipio().compareTo(f2.getMunicipio()));
Map<String, List<CidadeIbge>> estados = cidades.stream().collect(Collectors.groupingBy(CidadeIbge::getUf));
setKeyState(estados.keySet());
getKeyState().toString();
System.out.println(keyState);
}
Tks.
Sorry everyone for my uncompleted question.
My point is, when I select some value in my menu, this have to change another menu with the values in referente:
Front Implementation:
<h:panelGroup layout="block" class="col-md-3" id="panel-state">
<label>#{msg['state']}</label>
<h:selectOneMenu id="mdl-state" value="#{saisReportQueryBean.reportQuery.state}" binding="#{uf}" class="form-control input_no_round_corner">
<f:selectItem itemValue="#{null}" itemLabel="#{msg['select_state']}" noSelectionOption="true" />
<f:selectItems value="#{saisReportQueryBean.keyState}" var="estado" itemValue="#{estado}" itemLabel="#{estado}" />
<f:ajax listener="#{saisReportQueryBean.UpdateCityByState(uf.value)}" render=":panel-city" event="change" execute="#this" onevent="initializeChosenFieldsCity">
</f:ajax>
</h:selectOneMenu>
</h:panelGroup>
<h:panelGroup layout="block" class="col-md-3" id="panel-city">
<label>#{msg['city']}</label>
<h:selectOneMenu id="mdl-city" value="#{saisReportQueryBean.listCidades}" class="form-control input_no_round_corner">
<f:selectItem itemValue="#{null}" itemLabel="#{msg['select_city']}" noSelectionOption="true" />
<f:selectItems value="#{saisReportQueryBean.listCidades}" var="cidade" itemValue="#{cidade.municipio}" itemLabel="#{cidade.municipio}" />
</h:selectOneMenu>
</h:panelGroup>
Back implementation:
cidades = cidadesIbgeBeanRemote.findAll();
setKeyState(new ArrayList(estados.keySet()));
getKeyState().toString();
getKeyState().sort((f1, f2) -> f1.compareTo(f2));

Primefaces ajax not working update on field datatable

I have problem with "" component in my application. I have a datatable with 2 fields editable first is an inputtext and second field is a dateInput.
Inside fields I put to update value in list but when submit it to bean not updated the values.
Below is my page.xhtml and bean.
<p:dialog id="modalNovosParametrosRecesso" header="Salvar Novos Parâmetros de Estagiário"
widgetVar="widgetvarNovoParametro"
draggable="true" resizable="false"
closable="false" modal="true" width="630">
<h:outputText styleClass="modalRecessoAuto" value="#{msg.MN064}" escape="false" />
<br />
<h:panelGroup>
<br />
<p:dataTable id="tableRegRecessoAuto" var="recessoAuto"
value="#{parametroEstagiarioMB.visao.listaOcorrenciaRegistroRecesso}"
styleClass="hide-column-names" rowIndexVar="rowIndex" >
<p:column style="width:98px;">
<h:outputLabel value="#{rowIndex+1}º Recesso de " style="color: #0039BA" />
<p:inputText value="#{recessoAuto.diasRecesso}" size="2">
<p:ajax event="blur" update=":frmFiltro:tableRegRecessoAuto" ignoreAutoUpdate="true" global="false" />
</p:inputText>
<h:outputLabel value="dia(s) começando em " style="color: #0039BA" />
<p:inputMask value="#{recessoAuto.dtInicioOcorrencia}" mask="99/99/9999" size="10">
<f:convertDateTime pattern="dd/MM/yyyy" locale="pt_BR" />
<p:ajax event="blur" update=":frmFiltro:tableRegRecessoAuto" ignoreAutoUpdate="true" global="false"/>
</p:inputMask>
<h:outputLabel value=" e finalizando em " style="color: #0039BA; margin-left: 5px;"/>
<h:outputLabel id="dtLbl1" value="#{recessoAuto.dtFimOcorrencia}" style="color: #0039BA; margin-left: 5px;" >
<f:convertDateTime for="dtLbl1" pattern="dd/MM/yyyy" locale="pt_BR"/>
</h:outputLabel>
</p:column>
-->
<div style="padding-left: 170px;">
<p:commandLink styleClass="btnLaranja marginTop"
ignoreAutoUpdate="true" global="false" ajax="false" action="#{parametroEstagiarioMB.salvarRecessoPrimeiraParametrizacao()}"
update=":frmFiltro:tableRegRecessoAuto">
<span>Confirmar</span>
</p:commandLink>
<p:commandLink styleClass="btnLaranja marginTop"
id="btnCancelarRecessoAuto"
oncomplete="PF('widgetvarNovoParametro').hide();"
ignoreAutoUpdate="true" global="false" actionListener="#{parametroEstagiarioMB.cancelar}">
<f:setPropertyActionListener
target="#{parametroEstagiarioMB.visao.exibirModal}"
value="#{false}" />
<span>Cancelar</span>
</p:commandLink>
<p:commandLink styleClass="btnLaranja marginTop"
id="btnVerRegrasAuto"
oncomplete="PF('widgetvarModalRegras').show();"
ignoreAutoUpdate="true" global="false">
<span>Regras</span>
</p:commandLink>
</div>
</p:dialog>
My Bean:
public void salvarRecessoPrimeiraParametrizacao(){
int count = 0;
final DataTable dataTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot()
.findComponent(":frmFiltro:tableRegRecessoAuto");
List<OcorrenciaPonto> teste = new ArrayList<OcorrenciaPonto>();
for(OcorrenciaPonto c : (List<OcorrenciaPonto>) dataTable.getValue()){
teste.add(c);
count+=1;
}}
datatable.getValues() not get new values and yes old values that displayed in screen.
Are you using getters and setters correctly?
Have you tried to use immediate="true" on input fields?
I saw you are using <p:ajax> . I had some troubles with this. Maybe, if you change to **<f:ajax>** this must works so well.

Java Primefaces how to work with elements placed in dataTable column header

When "selectOneMenu" is placed in the "dataTable" column header it:
1) triggers row sorting everytime it is opened or after the button next to it is clicked and "selectOneMenu" is opened (it shouldn't be like that);
2) fails to assign value to the backing bean.
How can "selectOneMenu" be attached to the column header so that these problems wouldn't occur?
*.xhtml code with dataTable which causes 1) and 2) problems:
<h:form id="someForm0">
<p:dataTable id="sdt" var="variable" value="#{otherBean.tableModel}" rows="10">
<p:column sortBy="#{variable.name}" filterBy="#{variable.name}" filterMatchMode="contains" >
<f:facet name="header">
<h:outputText value="Name"/>
<h:panelGrid columns="2" cellpadding="1">
<p:selectOneMenu id="abc" value="#{userBean.someChars}">
<f:selectItem itemLabel="" itemValue="select" />
<f:selectItem itemLabel="AAA" itemValue="AAA" />
<f:selectItem itemLabel="BBB" itemValue="BBB" />
<f:selectItem itemLabel="CCC" itemValue="CCC" />
</p:selectOneMenu>
<h:commandButton id="btn" value="Submit" type="submit" action="#{userBean.submitChars}"/>
</h:panelGrid>
</f:facet>
<h:outputText value="#{variable.name}"/>
</p:column>
</p:dataTable>
</h:form>
Backing bean code:
#ManagedBean
public class UserBean
{
private String someChars;
public String getSomeChars()
{
return someChars;
}
public void setSomeChars(String someChars)
{
this.someChars = someChars;
}
public String submitChars()
{
if(getSomeChars() != null)
{
System.out.println("Selected chars are: " + getSomeChars());
}
else
{
System.out.println("Selected chars are equal to null!");
}
return null;
}
}
Here is fragment of the previously mentioned *.xhtml code, and selectOneMenu works just great when placed into the basic form:
<h:form id="someForm">
<p:selectOneMenu id="abc" value="#{userBean.someChars}">
<f:selectItem itemLabel="" itemValue="select" />
<f:selectItem itemLabel="AAA" itemValue="AAA" />
<f:selectItem itemLabel="BBB" itemValue="BBB" />
<f:selectItem itemLabel="CCC" itemValue="CCC" />
</p:selectOneMenu>
<h:commandButton id="btn" value="Submit" type="submit" action="#{userBean.submitChars}"/>
</h:form>
I think the last resort would be adding elements from the dataTable column header to the dataTable header:
<h:form id="someForm1">
<p:dataTable id="sdt" var="variable" value="#{otherBean.tableModel}" rows="10">
<f:facet name="header">
<h:panelGrid columns="2" cellpadding="1">
<p:selectOneMenu id="abc" value="#{userBean.someChars}">
<f:selectItem itemLabel="" itemValue="select" />
<f:selectItem itemLabel="AAA" itemValue="AAA" />
<f:selectItem itemLabel="BBB" itemValue="BBB" />
<f:selectItem itemLabel="CCC" itemValue="CCC" />
</p:selectOneMenu>
<h:commandButton id="btn" value="Submit" type="submit" action="#{userBean.submitChars}"/>
</h:panelGrid>
</f:facet>
<p:column sortBy="#{variable.name}" filterBy="#{variable.name}" filterMatchMode="contains" >
<f:facet name="header">
<h:outputText value="Name"/>
</f:facet>
<h:outputText value="#{variable.name}"/>
</p:column>
</p:dataTable>
</h:form>
Try as below :
<h:form id="someForm0">
<p:dataTable id="sdt" ...>
<p:column headerText="header">
<p:selectOneMenu id="abc" value="#{userBean.someChars}">
<f:selectItem itemLabel="" itemValue="select" />
<f:selectItem itemLabel="AAA" itemValue="AAA" />
<f:selectItem itemLabel="BBB" itemValue="BBB" />
<f:selectItem itemLabel="CCC" itemValue="CCC" />
<p:ajax event="valueChange" update=":someForm0:sdt"/>
</p:selectOneMenu>
</p:column>
</p:dataTable>
<h:commandButton ....>
</h:form>
UserBean.java
private String someChars;
public String getSomeChars() {
return someChars;
}
public void setSomeChars(Stirng someChars) {
this.someChars = someChars;
}

JSF Primefaces: how to update selectOneMenu(in form1) from dialogBox in form 2?

I want to update a selectOneMenu in form1 after submitting the commandbutton in form2. It is now only visible after a refresh of the page.
I have a selectOneMenu in form 1:
<h:form id="form1" rendered="#">
<p:spacer height="30" />
<h:selectOneMenu id="oneMenu" value="#{bean.value}">
<f:selectItem itemLabel="Select Value" itemValue="" />
<f:selectItems id="itemValues"
value="#{bean.allItems}" var="allItems"
itemValue="#{allItems}" itemLabel="#{allItems.name}" />
</h:selectOneMenu>
and a DialogBOX in form2:
<h:form id="form2">
<p:dialog header="Create new Item" widgetVar="newItem"
resizable="false">
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="item" value="Itemname:" />
<p:inputText id="itemname" value="#{bean.itemName}" />
</h:panelGrid>
<p:commandButton value="Submit"
actionListener="#{bean.newItem}"
update="form1:oneMenu" oncomplete="newItem.hide();" />
</p:dialog>
I've tried update="form1:oneMenu" but it doesn't work. I've also read this post
but it doesn't work either.
Thanks for help.
Make sure to use update=":form1:myPanel".
Example :
<h:form id="form1">
<h:selectOneMenu id="oneMenu" value="#{bean.value}">
...
</h:selectOneMenu>
</h:form>
<h:form id="form2">
<p:dialog ..>
...
<p:commandButton value="Submit" update=":form1:oneMenu" ..../>
</p:dialog>
</h:form>
Otherwise
<h:form id="form1">
<p:selectOneMenu id="oneMenu" value="#{bean.value}">
...
</p:selectOneMenu>
</h:form>
<h:form id="form2">
<p:dialog ..>
...
<p:commandButton value="Submit" update=":form1:oneMenu" ..../>
</p:dialog>
</h:form>
Update For Comment : Try that below. You can use h:selectOneMenu or p:selectOneMenu.
<h:form id="form1">
<p:selectOneMenu style="width:195px;" required="true" id="cityMenu">
<f:selectItems value="#{SelectOneMenuBean.cities}"/>
</p:selectOneMenu>
<p:commandButton oncomplete="newItem.show()" value="Show Dialog"/>
</h:form>
<h:form id="form2">
<p:dialog header="Create new Item" widgetVar="newItem" resizable="false">
<h:panelGrid columns="2" style="margin-bottom:10px">
<h:outputLabel for="item" value="Itemname:" />
<p:inputText id="itemname" value="#{SelectOneMenuBean.selectedValue}" />
</h:panelGrid>
<p:commandButton value="Submit" update=":form1:cityMenu" oncomplete="newItem.hide();" />
</p:dialog>
</h:form>
public class SelectOneMenuBean {
private String selectedValue;
public String getSelectedValue() {
return selectedValue;
}
public void setSelectedValue(String selectedValue) {
this.selectedValue = selectedValue;
}
public String[] getCities() {
if(selectedValue != null && selectedValue.equals("AAA")) {
return new String[] {"City_1 of AAA", "City_2 of AAA", "City_3 of AAA"};
} else if(selectedValue != null && selectedValue.equals("BBB")) {
return new String[] {"City_1 of BBB", "City_2 of BBB", "City_3 of BBB"};
} else if(selectedValue != null && selectedValue.equals("CCC")) {
return new String[] {"City_1 of CCC", "City_2 of CCC", "City_3 of CCC"};
} else if(selectedValue != null && selectedValue.equals("DDD")) {
return new String[] {"City_1 of DDD", "City_2 of DDD", "City_3 of DDD"};
}
return new String[] {"No City"};
}
}
Note : If you input value AAA,BBB,CCC and DDD in dialog, the values of selectedOneMenu will be changed.

How to make two JSF selectOneMenus that depend on each other with AJAX?

I have two selectOneMenu. I need following:
On first menu change I need to populate second one and some form's fields with AJAX
On second menu change I need to populate only some form's fields wit AJAX.
Populating second menu and form's fields on step 1 is perfect and right after first menu change, but there is a problem with populating form on step 2.
Nothing happens when I change second menu's value. But when I returned second menu value to NoSelectionOption ajax listener invoked. It seems that AJAX listener ignores values that was added with AJAX.
Here's my code fragments:
JSF:
<h:panelGrid>
<h:panelGrid columns="1">
<h:panelGrid columns="1">
<h:panelGrid columns="2">
<h:outputText value="Получатель:" />
<h:selectOneMenu value="#{paymentOrder.curContractor}">
<f:selectItem itemLabel="Выберите контрагента .." noSelectionOption="true" />
<f:selectItems value="#{paymentOrder.userContractors}" var="contr"
itemValue="#{contr.idcontractor}"
itemLabel="#{contr.pnamecontractor}"/>
<a4j:ajax event="valueChange" listener="#{paymentOrder.valueContractorChanged}" render="idINNContractor, idKPPContractor, idNameContractor, idContractorAccounts" execute="#this"/>
</h:selectOneMenu>
</h:panelGrid>
<h:panelGrid columns="1">
<h:panelGrid columns="4">
<h:outputText value="ИНН"/>
<h:inputText id="idINNContractor" value="#{paymentOrder.chosenContractor.inncontractor}"/>
<h:outputText value="КПП"/>
<h:inputText id="idKPPContractor" value="#{paymentOrder.chosenContractor.kppcontractor}"/>
</h:panelGrid>
<h:panelGrid columns="2">
<h:outputText value="Получатель"/>
<h:inputTextarea id="idNameContractor" value="#{paymentOrder.chosenContractor.pnamecontractor}"/>
</h:panelGrid>
</h:panelGrid>
<h:panelGrid columns="1">
<h:panelGrid columns="2">
<h:outputText value="Счёт получателя:"/>
<h:selectOneMenu id="idContractorAccounts" value="#{paymentOrder.curContractorAccount}">
<f:selectItem itemLabel="Выберите счёт .." noSelectionOption="true" />
<f:selectItems value="#{paymentOrder.contractorAccounts}" var="acc"
itemValue="#{acc.naccountcontractor}"
itemLabel="#{acc.advName}"/>
<a4j:ajax event="valueChange" listener="#{paymentOrder.valueAccountChanged}" render="idContrAcc, idNameContrBank, idBikContrBank, idAccContrBank" execute="#this"/>
</h:selectOneMenu>
</h:panelGrid>
<h:panelGrid columns="2">
<h:outputText value="Сч.№"/>
<h:inputText id="idContrAcc" value="#{paymentOrder.curContractorAccount}"/>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
<h:panelGrid columns="1">
<h:panelGrid columns="4">
<h:panelGrid columns="2">
<h:outputText value="Банк получателя"/>
<h:inputTextarea id="idNameContrBank" value="#{paymentOrder.chosenBank.namebank}" />
</h:panelGrid>
<h:panelGrid columns="2">
<h:outputText value="БИК"/>
<h:inputText id="idBikContrBank" value="#{paymentOrder.chosenBank.bikbank}"/>
<h:outputText value="Сч.№"/>
<h:inputText id="idAccContrBank" value="#{paymentOrder.chosenBank.bankkorshet}"/>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
</h:panelGrid>
And my back bean fragment:
public class PaymentOrder {
#EJB(lookup="JpaBankBean/local")
private JpaBankBeanLocal jpaBean;
private Paymentdocument pDocument;
private Paymentorder pOrder;
private Klbankrf chosenBank;
private String curContractorAccount;
private String curContractorBank;
private String curContractor;
private String err;
private String chosenAccount;
private Contractor chosenContractor;
#SuppressWarnings("rawtypes")
private Set contractorAccounts;
#SuppressWarnings("rawtypes")
private List contractorBanks;
private String userName;
private Date nowDate;
public PaymentOrder() {
this.nowDate = Calendar.getInstance().getTime();
Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();
if (principal instanceof UserDetails) {
setUserName(((UserDetails)principal).getUsername());
} else {
setUserName(principal.toString());
}
pDocument = new Paymentdocument();
pOrder = new Paymentorder();
chosenContractor = new Contractor();
chosenBank = new Klbankrf();
}
public void valueContractorChanged()
{
chosenContractor = jpaBean.getContractor(Integer.valueOf(getCurContractor()));
setContractorAccounts(jpaBean.getContractorAccounts(Integer.valueOf(getCurContractor())));
pDocument.setReceiver(chosenContractor.getPnamecontractor());
}
public List getUserContractors()
{
return jpaBean.getUserContractors(userName);
}
public void valueAccountChanged()
{
chosenBank.setNamebank("SBER");
//TODO chosenBank = jpaBean.getContractorBank(getCurContractorAccount());
//TODO setChosenAccount("012345678901234567890");
}
}
So, "SBER" appear in idNameContrBank field only if I change second menu value to somethig and then change back to NoSelectOption. It is strange to me.
I use RichFaces 4, JBoss AS 6.
I've found some information at this forum, but there is no solution.
How to make second menu to change something? Or is there my mistake? Any ideas?
Thanks in advance!
I've made some experiments.
When I change second menu to some value populated with AJAX, page gets response like that:
<?xml version='1.0' encoding='UTF-8'?>
<partial-response>
<changes>
<update id="docForm:idContrAcc">
<![CDATA[<input id="docForm:idContrAcc" type="text" name="docForm:idContrAcc" style=" width : 100%;" />]]>
</update>
<update id="docForm:idNameContrBank">
<![CDATA[<textarea id="docForm:idNameContrBank" name="docForm:idNameContrBank" style=" width : 130px;"></textarea>]]>
</update>
<update id="docForm:idBikContrBank">
<![CDATA[<input id="docForm:idBikContrBank" type="text" name="docForm:idBikContrBank" style=" width : 140px;" />]]>
</update>
<update id="docForm:idAccContrBank">
<![CDATA[<input id="docForm:idAccContrBank" type="text" name="docForm:idAccContrBank" style=" width : 140px;" />]]>
</update>
<update id="javax.faces.ViewState"><![CDATA[3312710224811729695:3995303008700914422]]>
</update>
</changes>
</partial-response>
There are no values, but right IDs! How it can be? Why?
But if I return NoSelectionOption active then page gets response
<?xml version='1.0' encoding='UTF-8'?>
<partial-response>
<changes>
<update id="docForm:idContrAcc">
<![CDATA[<input id="docForm:idContrAcc" type="text" name="docForm:idContrAcc" value="" style=" width : 100%;" />]]>
</update>
<update id="docForm:idNameContrBank">
<![CDATA[<textarea id="docForm:idNameContrBank" name="docForm:idNameContrBank" style=" width : 130px;">SBER</textarea>]]>
</update>
<update id="docForm:idBikContrBank">
<![CDATA[<input id="docForm:idBikContrBank" type="text" name="docForm:idBikContrBank" style=" width : 140px;" />]]>
</update>
<update id="docForm:idAccContrBank">
<![CDATA[<input id="docForm:idAccContrBank" type="text" name="docForm:idAccContrBank" style=" width : 140px;" />]]>
</update>
<update id="javax.faces.ViewState">
<![CDATA[3312710224811729695:3995303008700914422]]>
</update>
</changes>
</partial-response>
It's seems OK - values are presented! But why does it happen when NoSelectionOption is active?!
I suspect JSF might be overwriting your attempts since it usually calls all the setters for all the properties exposed on the page and it normally does this after the valueChangeListeners are executed. I've never seen the <a4j:ajax /> tag but you could try the <a4j:support /> tag. Instead of this:
<a4j:ajax event="valueChange" listener="#{paymentOrder.valueContractorChanged}" render="idINNContractor, idKPPContractor, idNameContractor, idContractorAccounts" execute="#this"/>
Try this:
<a4j:support event="onchange" ajaxSingle="true" reRender="idINNContractor, idKPPContractor, idNameContractor, idContractorAccounts"/>
Since ajaxSingle="true" is included in the tag it means that only the setter for curContractor will be called (and not all the rest on the page like JSF normally does). Then you can call valueContractorChanged from the setter (or even just make it part of the setter).
If you replace all of the <a4j:ajax /> tags in this way you should get the desired result. Check out more info about the tag via the link above.

Categories