Primefaces ajax not working update on field datatable - java

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.

Related

Why Primefaces commandButton does not redirect to the page?

I use primefaces version 6.2 in combination with jsf and trinidaad.
In the project I have a table with each row containing a button to redirect this page to another page based on selected row.
jsf and trindad commandLink and commandButton does the job but primefaces commandLink and command button doesn't.
What I have already done:
Changed the type of button to type="button"
Added immediate="true"
I used actionListener="#{coolingBean.view(row)}" instead of action="#{coolingBean.view}".
Anyone know why and what should I change?
<p:column id="viewButtonColumn" exportable="false" style="text-align: center" >
<tr:commandLink textAndAccessKey="&view " id="viewButton" action="#{coolingBean.view}" styleClass="commandLinkMediumSmallFont" onclick="PF('bui').show()">
<tr:image source="/imgs/view.png" styleClass="commandLinkImageWithText"/>
<f:setPropertyActionListener value="#{row.number}" target="#{coolingBean.criteria.number}"/>
<f:setPropertyActionListener value="#{row.id}" target="#{searchBean.selectedId}"/>
</tr:commandLink>
</p:column>
<p:column id="viewButtonColumn1" exportable="false" style="text-align: center" >
<h:commandLink textAndAccessKey="&view " id="viewButton1" action="#{coolingBean.view}" styleClass="ui-priority-primary" onclick="PF('bui').show()">
<i class="fa fa-search" ></i>
<f:setPropertyActionListener value="#{row.number}" target="#{coolingBean.criteria.number}"/>
<f:setPropertyActionListener value="#{row.id}" target="#{searchBean.selectedId}"/>
</h:commandLink>
</p:column>
<p:column id="viewButtonColumn2" exportable="false" style="text-align: center" >
<p:commandLink value="View" id="commandLinkView" action="#{coolingBean.view}" styleClass="ui-priority-primary" onclick="PF('bui').show()">
<i class="fa fa-search" ></i>
<f:setPropertyActionListener value="#{row.number}" target="#{coolingBean.criteria.number}"/>
<f:setPropertyActionListener value="#{row.id}" target="#{searchBean.selectedId}"/>
</p:commandLink>
</p:column>
<p:column id="viewButtonColumn3" exportable="false" style="text-align: center" >
<p:commandButton id="viewButton2" value="View" action="#{coolingBean.view}" icon="fa fa-search" immediate="true" type="button" onclick="PF('bui').show()">
<f:setPropertyActionListener value="#{row.number}" target="#{coolingBean.criteria.number}"/>
<f:setPropertyActionListener value="#{row.id}" target="#{searchBean.selectedId}"/>
</p:commandButton>
</p:column>
Inside managed Bean
public String view(Row selectedRow) {
if(criteria == null)
criteria = new criteriaBean();
criteria.setNummer(selectedRow.getNummber());
searchBean.selectedId = selectedRow.getId();
//FacesContext.getCurrentInstance().getExternalContext().dispatch("view.jsp");
return view();
}
public String view(){
return"view';
}
This one actually helped me.
Basically adding one of the following did the trick for me:
Adding ajax="false" into the commandButton
Appending ?faces-redirect=true to the url ( e.g. return "view?faces-redirect=true';)

p:inputText in p:dialog return empty values to bean

I'm trying get a value from a p:inputText is inside a p:dialog but this is returning null to my bean.
The inputText motivoCancelamento needs to be filled with the content of my inputText motivoCancelamentoDialog inside the dialog.
The another ones are ok, like status, protocoloCancelamento and dataCancelamento.
Can anyone help me?
<h:form id="form">
<p:toolbar>
<f:facet name="left">
<p:growl id="messages" showDetail="true"/>
<p:dialog header="Cancelar Nota" widgetVar="cancelamentoDialog" focus="motivoCancelamentoDialog">
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="motivoCancelamentoDialog" value="Motivo Cancelamento:" />
<p:inputText id="motivoCancelamentoDialog" value="#{notaProdutoBean.notaProduto.motivoCancelamento}" />
<p:commandButton value="Cancelar" actionListener="#{notaProdutoBean.cancelarNota()}" update="status motivoCancelamento protocoloCancelamento dataCancelamento messages form"/>
</h:panelGrid>
</p:dialog>
<p:confirmDialog global="true" showEffect="fade" hideEffect="fade">
<p:commandButton value="Sim" type="button" styleClass="ui-confirmdialog-yes" icon="ui-icon-check" />
<p:commandButton value="Não" type="button" styleClass="ui-confirmdialog-no" icon="ui-icon-close" />
</p:confirmDialog>
</p:toolbar>
<p:fieldset id='panelNotaFiscal' legend="NotaFiscal" >
<p:panelGrid columns="6" columnClasses="centered">
<p:outputLabel for='status' value='Status'/>
<p:inputText id="status" value="#{notaProdutoBean.notaProduto.status}" required="true" requiredMessage="O campo Status é obrigatório">
<p:message for="status"/>
</p:inputText>
<p:outputLabel for="motivoCancelamento" value="Motivo Cancelamento"/>
<p:inputText id="motivoCancelamento" size="25" value="#{notaProdutoBean.notaProduto.motivoCancelamento}">
<p:message for="motivoCancelamento"/>
</p:inputText>
<p:outputLabel for="protocoloCancelamento" value="Protocolo Cancelamento"/>
<p:inputText id="protocoloCancelamento" size="15" value="#{notaProdutoBean.notaProduto.protocoloCancelamento}">
<p:message for="protocoloCancelamento"/>
</p:inputText>
<p:outputLabel for="dataCancelamento" value="Data Cancelamento"/>
<p:calendar id="dataCancelamento" value="#{notaProdutoBean.notaProduto.dataCancelamento}" pattern="dd/MM/yyyy HH:mm:ss">
<p:message for='dataCancelamento'/>
</p:calendar>
</p:panelGrid>
</p:fieldset>
public void cancelarNota(){
try{
if(getNotaProduto().getStatus().equals("Autorizada")){
getNotaProduto().setStatus("Cancelada");
System.out.println("Motivo " + getNotaProduto().getMotivoCancelamento());
getNotaProduto().setProtocoloCancelamento("22222222222222");
getNotaProduto().setDataCancelamento(new Date());
new BaseBean().salvar(getNotaProduto());
RequestContext.getCurrentInstance().execute("PF('cancelamentoDialog').hide();");
}
else{
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO ,"Mensagem: ", "A nota não está autorizada portanto não pode ser cancelada"));
}
}
catch(Exception e){
new Log().salvaErroLog(e);
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR ,"Mensagem: ", "Um erro ocorreu, entre em conto com o adminstrador"));
}
}
You have 2 inputs for the same field in the same form:
<p:inputText id="motivoCancelamentoDialog" value="#{notaProdutoBean.notaProduto.motivoCancelamento}" />
<p:inputText id="motivoCancelamento" size="25" value="#{notaProdutoBean.notaProduto.motivoCancelamento}">
<p:message for="motivoCancelamento"/>
</p:inputText>
you should put the dialog in a separate form so it doesnt post the second input.
also you can specify the elements to process in the "cancelar" button
<p:inputText id="motivoCancelamentoDialog" value="# notaProdutoBean.notaProduto.motivoCancelamento}" />
<p:commandButton value="Cancelar" actionListener="#{notaProdutoBean.cancelarNota()}" update="status motivoCancelamento protocoloCancelamento dataCancelamento messages form" process="#this, motivoCancelamentoDialog"/>
your input tag is actually empty tag
<p:inputText id="motivoCancelamentoDialog" value="#{notaProdutoBean.notaProduto.motivoCancelamento}" />
try using something like below to see if it works.
<p:inputText id="motivoCancelamentoDialog" value="#{notaProdutoBean.notaProduto.motivoCancelamento}">abc</p:inputText>

dynamic page content with primefaces

I'm creating a web page. The content should change according to user selection.
I require 2 radio buttons which give the option to select one day and many days (start date and end date) if one day selected page should display one calender to select date else two calenders to select start date and end date I tried to use rendered propety with ajax but I can't view calenders how could i do this
my xhtml
<h:form id="f1">
<p:growl id="createmsg"/>
<h:panelGrid columns="2" cellpadding="10">
<p:panel id="add_visitor_details_pnl" style="width:100%">
<h:panelGrid id="grid" columns="2" cellpadding="10">
<h:outputText value="Organization :" />
<p:selectOneMenu editable="true" value="#{visitorBean.organization}" style="width:160px" filter="true" filterMatchMode="startsWith">
<f:selectItems value="#{visitorBean.organizations}" />
</p:selectOneMenu>
<h:outputText value="Visitor Name :" />
<p:selectOneMenu value="#{visitorBean.name}" style="width:160px" filter="true" filterMatchMode="startsWith">
<f:selectItems value="#{visitorBean.names}" />
</p:selectOneMenu>
<h:outputText value="Visitor ID :" />
<p:selectOneMenu value="#{visitorBean.id}" style="width:160px" filter="true" filterMatchMode="startsWith">
<f:selectItems value="#{visitorBean.ids}" />
</p:selectOneMenu>
<h:outputText value="Purpose :" />
<p:inputTextarea id="purpose_it" value="#{visitorBean.purpose}" required="true" autoResize="false"
requiredMessage="Enter Purpose" rows="10" cols="50"/>
</h:panelGrid>
<h:panelGrid columns="1" cellpadding="10">
<p:selectOneRadio id="customRadio" value="#{visitorBean.option}" >
<f:selectItem itemLabel="Create a one day appointment" itemValue="1" />
<f:selectItem itemLabel="create a day period appointment" itemValue="2" />
<p:ajax event="change" listener="#{visitorBean.selectDayType()}"
update=":f1:add_visitor_details_pnl" />
</p:selectOneRadio>
</h:panelGrid>
<h:panelGrid id="date" columns="3" cellpadding="10">
<h:outputText id="date1" value="Date" rendered="#{visitorBean.cal1}"/>
<p:calendar id="calender_Cal1" value="#{visitorBean.date_time}"
pattern="yyyy-MM-dd" rendered="#{visitorBean.cal1}"
required="true" requiredMessage="Enter Date Time"/>
<p:calendar id="calender_Cal2" value="#{visitorBean.date_time}"
pattern="yyyy-MM-dd" rendered="#{visitorBean.cal2}"
required="true" requiredMessage="Enter Date Time"/>
</h:panelGrid>
<h:panelGrid columns="2" cellpadding="10">
<p:commandButton id="submit_visitor_Btn" value="Create"
action="#{visitorBean.submitVisitorData()}"
update=":f1:visitor_dataTable,:f1:grid,:f1:createmsg"/>
</h:panelGrid>
my ajax mthod
public void selectDayType(){
if(option =="1")
cal1 = "true";
else if(option =="2"){
cal1="true";
cal2="true";
}
Try surrounding the calendars with a:
<p:outputPanel id="someId" >
...
</p:outputPanel>
Primefaces - Output Panel

Autocomplete address with google map library in Primefaces

I'm working with Primefaces 3.4, Apache Tomcat 7 and Java EE. I read the GoogleMaps API but I can't get this feature to work.
I have a PrimeFaces input box, and when i write an address on it, i want to suggest other addresses provided by GoogleMaps library.
Nothing happens when a put the JavaScript code on my XHTML. I have the library of GoogleMaps too.
This is my XHTML:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<script type="text/javascript"
src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script type="text/javascript">
function initia(domicilioDesde, domicilioHasta) {
var directionsDisplay;
var directionsService = new google.maps.DirectionsService();
var map;
var oldDirections = [];
var currentDirections = null;
var cordoba = " ,Cordoba, Argentina";
var direccion = domicilioDesde; /* '#{busquedaplayaMB.direccionDesde}'; */
var start = direccion.concat(cordoba);
var fin = domicilioHasta; /*'#{busquedaplayaMB.playaselected.domicilio}';*/
var end = fin.concat(cordoba);
var request = {
origin : start,
destination : end,
travelMode : google.maps.DirectionsTravelMode.DRIVING
}
var myOptions = {
zoom : 13,
center : new google.maps.LatLng(#{busquedaplayaMB.latitudCentro},#{busquedaplayaMB.longitudCentro}),
mapTypeId : google.maps.MapTypeId.ROADMAP
}
map = new google.maps.Map(document.getElementById("map_canvas"),
myOptions);
directionsDisplay = new google.maps.DirectionsRenderer({
'map' : map,
'preserveViewport' : true,
'draggable' : true
});
directionsDisplay.setPanel(document
.getElementById("directions_panel"));
directionsService.route(request, function(response, status) {
if (status == google.maps.DirectionsStatus.OK) {
directionsDisplay.setDirections(response);
}
});
dlg2.show();
}
function undo() {
currentDirections = null;
directionsDisplay.setDirections(oldDirections.pop());
if (!oldDirections.length) {
setUndoDisabled(true);
}
}
function setUndoDisabled(value) {
document.getElementById("undo").disabled = value;
}
</script>
<h:form id="form">
<p:growl id="messages" showSummary="false" autoUpdate="true"
globalOnly="true" />
<div align="left" style="margin: 10px 0 10px 0;">
<p:panel>
<h:panelGrid columns="1" width="100%" cellspacing="5"
cellpadding="5">
<h:panelGrid columns="2" width="80%">
<p:column style="vertical-align:text-center;">
<h:panelGrid columns="2">
<p:column>
<p:watermark for="direccionBusqueda"
value="Dirección de búsqueda" />
<p:inputText id="direccionBusqueda"
value="#{busquedaplayaMB.direccionBusqueda}" required="true"
requiredMessage="Campo dirección de búsqueda obligatorio"
style="width:250px;">
<p:ajax event="blur" update="direccionBusquedaMsg" />
</p:inputText>
</p:column>
<p:column>
<p:message id="direccionBusquedaMsg" display="icon"
for="direccionBusqueda" />
</p:column>
</h:panelGrid>
</p:column>
<p:column>
<div align="center">
<h:outputLabel value="N° de cuadras: " />
<h:outputLabel id="nroCuadras"
value="#{busquedaplayaMB.distancia}" />
<h:inputHidden id="distancia"
value="#{busquedaplayaMB.distancia}" />
<p:slider for="distancia" minValue="1" maxValue="50"
style="width:100px;" update="nroCuadras" display="nroCuadras" />
</div>
</p:column>
</h:panelGrid>
<h:panelGrid columns="5" cellspacing="5" cellpadding="5"
width="100%">
<p:column style="vertical-align:text-center;">
<p:selectOneMenu value="#{busquedaplayaMB.categoriaParameter}"
effect="fade" style="width:160px;height:25px;line-height:17px;">
<f:selectItem itemLabel="Todas las categorías"
itemValue="#{null}" />
<f:selectItems
value="#{categoriaVehiculoMB.categoriaVehiculoList}"
var="categoria" itemValue="#{categoria}"
itemLabel="#{categoria.nombre}" />
<f:converter converterId="categoriaVehiculoConverter" />
</p:selectOneMenu>
</p:column>
<p:column style="vertical-align:text-center;">
<p:selectOneMenu value="#{busquedaplayaMB.tipoEstadiaParameter}"
effect="fade" style="width:160px;height:25px;line-height:17px;">
<f:selectItem itemLabel="Todas los tipos estadías"
itemValue="#{null}" />
<f:selectItems value="#{tipoEstadiaMB.tipoEstadiaList}"
var="tipoEstadia" itemValue="#{tipoEstadia}"
itemLabel="#{tipoEstadia.nombre}" />
<f:converter converterId="tipoEstadiaConverter" />
</p:selectOneMenu>
</p:column>
<p:column style="vertical-align:text-center;">
<div align="right">
<h:panelGrid columns="2">
<p:selectBooleanCheckbox id="check"
value="#{busquedaplayaMB.checkPromociones}" />
<p:outputLabel for="check" value="Sólo con promociones" />
</h:panelGrid>
</div>
</p:column>
<p:column>
<div align="right">
<p:commandButton id="btnBuscarAvanzado" update="playas,mapa"
value="Buscar" action="#{busquedaplayaMB.busquedaAvanzada}"
ajax="false" icon="ui-icon-search" style="width:85px;" />
</div>
</p:column>
</h:panelGrid>
</h:panelGrid>
</p:panel>
</div>
<div>
<p:panel>
<f:view contentType="text/html">
<!-- <h1>Playas encontradas:</h1> -->
<script src="http://maps.google.com/maps/api/js?sensor=false"
type="text/javascript"></script>
<p:gmap center="#{busquedaplayaMB.coordenadas}" zoom="14"
type="ROADMAP" model="#{busquedaplayaMB.advancedModel}"
style="width:99,5%; height:350px;">
<p:ajax event="overlaySelect"
listener="#{busquedaplayaMB.onMarkerSelect}" />
<p:gmapInfoWindow>
<ui:fragment
rendered="#{busquedaplayaMB.marker.data.playa == null}">
<div align="center">
<ui:fragment rendered="#{busquedaplayaMB.usuario == null}">
<h:outputText style="font-weight:bold;" value="¡Usted está aquí!" />
</ui:fragment>
<ui:fragment rendered="#{busquedaplayaMB.usuario != null}">
<h:panelGrid column="1" style="text-align:center;"
cellspacing="0px" cellpadding="0px">
<p:column>
<h:graphicImage library="fotos_perfil_usuarios"
name="sinfoto.jpg"
styleClass="bordes-foto-perfil-comentario"
rendered="#{busquedaplayaMB.usuario.fotoUsuario == null}" />
<h:graphicImage library="fotos_perfil_usuarios"
name="#{busquedaplayaMB.usuario.nombreUser}.jpg"
styleClass="bordes-foto-perfil-comentario"
rendered="#{busquedaplayaMB.usuario.fotoUsuario != null}" />
</p:column>
<p:column>
<h:outputText style="font-weight:bold;"
value="#{busquedaplayaMB.usuario.nombre} #{busquedaplayaMB.usuario.apellido}" />
</p:column>
<p:column>
<h:link id="linkUsuario" tittle="Ir a mi perfil"
value="Ir a mi perfil" outcome="/cliente/perfilcliente" />
</p:column>
</h:panelGrid>
</ui:fragment>
</div>
</ui:fragment>
<ui:fragment
rendered="#{busquedaplayaMB.marker.data.playa != null}">
<div align="center">
<h:panelGrid column="1" style="text-align:center;"
cellspacing="0px" cellpadding="0px">
<p:column>
<h:graphicImage library="fotos_perfil_playas"
name="#{busquedaplayaMB.marker.data.id}_#{busquedaplayaMB.marker.data.nombreFoto}"
styleClass="bordes-foto-perfil-comentario"
rendered="#{busquedaplayaMB.marker.data.nombreFoto != null}" />
<h:graphicImage library="fotos_perfil_playas"
name="sinfoto.jpg"
styleClass="bordes-foto-perfil-comentario"
rendered="#{busquedaplayaMB.marker.data.nombreFoto == null}" />
</p:column>
<h:outputText style="font-weight:bold;"
value="#{busquedaplayaMB.marker.data.playa.nombreComercial}" />
<h:outputText
value="#{busquedaplayaMB.marker.data.playa.domicilio} - #{busquedaplayaMB.marker.data.playa.barrio.nombre}" />
<h:link id="link" tittle="Ir a playa" value="Ver información"
outcome="/viewperfilplaya.html?id=#{busquedaplayaMB.marker.data.playa.id}" />
</h:panelGrid>
</div>
</ui:fragment>
</p:gmapInfoWindow>
</p:gmap>
</f:view>
</p:panel>
</div>
<div style="margin: 5px;">
<p:dataTable id="playas" var="playa" paginator="true"
paginatorPosition="bottom" rows="5"
emptyMessage="¡No existen playas!"
value="#{busquedaplayaMB.playaResultadoBusqueda}">
<p:column headerText="Nombre Comercial" styleClass="column-font">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{playa.nombreComercial}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{playa.nombreComercial}"
styleClass="input-font" />
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Barrio" styleClass="column-font">
<h:outputText value="#{playa.barrio.nombre}" />
</p:column>
<p:column headerText="Domicilio" styleClass="column-font">
<h:outputText value="#{playa.domicilio}" />
</p:column>
<p:column headerText="Perfil" style="text-align:center; width:50px;">
<h:link id="verPerfil" title="Ver perfil"
outcome="/viewperfilplaya.html?id=#{playa.id}">
<h:graphicImage library="images/icons" name="go.png" />
</h:link>
</p:column>
<p:column headerText="Ruta" style="text-align:center; width:50px;">
<p:commandLink id="view2" oncomplete="dlgOrigen.show();"
title="¿Cómo llegar a esta playa?" update=":dlgO" process="#this">
<f:setPropertyActionListener value="#{playa}"
target="#{busquedaplayaMB.playaselected}" />
<h:graphicImage library="images/icons" name="search-map.png"
style="height:40px; width:40px" />
</p:commandLink>
</p:column>
</p:dataTable>
</div>
<!-- </h:form> -->
<p:dialog widgetVar="dlg2" width="800" height="400" modal="true"
id="dialog" draggable="false" closable="true">
<!-- <h:form id="frmComoLlegar"> -->
<f:facet name="header">
<h:outputText value="¿Cómo llegar a la playa?" />
</f:facet>
<div id="map_canvas" style="float: left; width: 65%; height: 100%"></div>
<div style="float: right; width: 35%; height: 100%; overflow: auto">
<div id="directions_panel" style="width: 100%"></div>
</div>
<f:facet name="footer" style="text-align=right;">
<p:commandButton id="undo" value="Volver"
style="float:right; width:274px; height: 42px" onclick="undo();"></p:commandButton>
</f:facet>
</p:dialog>
</h:form>
<p:dialog header="Dirección de origen" id="dlgO" widgetVar="dlgOrigen"
resizable="false" closable="true">
<h:form id="frmComoLlegar">
<h:panelGrid columns="2" cellspacing="10" cellpadding="10">
<h:outputLabel for="dirOrigen" value="Dirección de origen: " />
<p:inputText id="dirOrigen" required="true"
value="#{busquedaplayaMB.direccionDesde}"
onkeyup="if (event.keyCode == 13) { document.getElementById(':frmComoLlegar:siguiente').click(); return false; }" />
<p:column />
<p:column>
<div align="right">
<p:commandButton id="siguiente" value="Siguiente" ajax="true"
onclick="initia(jQuery('#frmComoLlegar\\:dirOrigen').val(), '#{busquedaplayaMB.playaselected}');"
update=":dialog" process="#this"
action="#{busquedaplayaMB.tomarDomicilioDesde}" />
</div>
</p:column>
</h:panelGrid>
</h:form>
</p:dialog>
I have implemented this feature using GMap3 jQuery Plugin (also in combination with JSF + Primefaces). See this for an example: https://github.com/jbdemonte/gmap3/blob/master/examples/autocomplete/autocomplete.html

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