primefaces calendar doesn't display when update - jsf

I got a problem with the Primefaces calendar.
It is not show in my Application when updated from other side.
Here, the primefaces calendar it's perfect working
<p:outputPanel id="calTask">
<p:calendar id="calendarTask" value="#{taskAddBean.dateEnd}" showOn="button">
<p:ajax event="dateSelect"
listener="#{taskAddBean.changeDates}"
/>
</p:calendar>
</p:outputPanel>
but in the next case, the primefaces calendar doesn't display de popup.
<h:selectOneMenu value="#{taskAddBean.selectedActType}">
<f:selectItems value="#{taskAddBean.lstActType}" />
<p:ajax listener="#{taskAddBean.actTypeChanged}"
update="calTask" />
</h:selectOneMenu> </div>
<p:outputPanel id="calTask">
<p:calendar id="calendarTask" value="#{taskAddBean.dateEnd}" showOn="button">
<p:ajax event="dateSelect"
listener="#{taskAddBean.changeDates}"
/>
</p:calendar>
</p:outputPanel>
I don't understand what is the razon
Thanks :)

Related

Primefaces 5: selectOneMenu isn't making listener calls after being updated

Code worked in a older version of Primefaces, but is failing in Primefaces 5.0. It's supposed to let a user pick an item in the first selectOneMenu (Group), which populates the second selectOneMenu (that part works). When the user selects an item from the second selectOneMenu, it's supposed to pull the matching code and update the Code, which isn't working. I can see that the listener in the Sub Group selectOneMenu isn't being called.
What am I doing wrong?
<h:outputLabel for="group" value="Group: *" />
<p:selectOneMenu id="group" label="Group" value="#{codeViewController.model.group}" style="width:100%">
<f:selectItems value="#{Session.groups}" />
<p:ajax event="change" listener="#{codeViewController.fetchSubGroup}" update="subGroup"/>
</p:selectOneMenu>
<p:message for="group" />
<h:outputLabel for="subGroup" value="Sub Group: *" />
<p:selectOneMenu id="subGroup" label="Sub Group" value="#{codeViewController.model.subGroup}" style="width:100%">
<f:selectItems value="#{codeViewController.model.subGroups}" />
<p:ajax event="change" listener="#{codeViewController.fetchCode}" update="code"/>
</p:selectOneMenu>
<p:message for="subGroup" />
<h:outputLabel for="code" value="Code: *" />
<p:inputText id="code" value="#{codeViewController.model.group.id.code}" label="Code">
<f:validateLength minimum="5" />
</p:inputText>
<p:message for="code" />

How do I force a Primefaces calendar to update after a change Ajax event validates the new value?

I'm modifying a page with two Calendar components, to select a start date and an end date. I'm supposed to make them check that the start date is before the end date whenever you modify either of them; if the start is set after the end or viceversa, the code changes the end date to the maximum date and pops a warning.
The event listeners run correctly, but the end date calendar fails to update to reflect the new value; it's not that it updates before the listener changes the value ─it fails to update at all.
The project runs on Primefaces 5.3 and Java 1.6. This is the xhtml (minus styles for readability):
<p:outputPanel id="fl83">
<p:outputPanel id="fl83c3">
<h:outputLabel value="Start date" for="fechaInicioMP" />
<p:calendar locale="es" pattern="dd/MM/yyyy" id="fechaInicioMP"
maxdate="#{filtroFechasBB.fechaMaxFin}" value="#{filtroFechasBB.fechaInicio}"
onSelectUpdate=":f183" >
<p:ajax event="blur" />
<f:ajax event="change" listener="#{filtroFechasBB.fechaInicioTextChange}"
render="#this" update="#form" />
<p:ajax event="dateSelect" listener="#{filtroFechasBB.fechaInicioClickChange}"
update="#form" />
</p:calendar>
</p:outputPanel>
<p:outputPanel id="fl83c4">
<h:outputLabel value="End date" for="fechaFinMP" />
<p:calendar locale="es" pattern="dd/MM/yyyy" id="fechaFinMP"
maxdate="#{filtroFechasBB.fechaMaxFin}" value="#{filtroFechasBB.fechaFin}"
onSelectUpdate=":f183" >
<p:ajax event="blur" />
<f:ajax event="change" listener="#{filtroFechasBB.fechaFinTextChange}"
render="#this" update=":fl83" />
<p:ajax event="dateSelect" listener="#{filtroFechasBB.fechaFinClickChange}"
update=":fl83" />
</p:calendar>
</p:outputPanel>
</p:outputPanel>
And these are the listeners:
public void fechaFinTextChange() {
if(fechaFin.after(fechaMaxFin)) {
fechaFin = fechaMaxFin;
addErrorMessage(FFIN_AFTER_FMAX);
}
compareInicioBeforeFin();
}
public void fechaFinClickChange(SelectEvent event) {
setFechaFin((Date)event.getObject()); // I couldn't find out why this is here given that
// the setter has already been called
compareInicioBeforeFin();
if (updateMetodoEntreBB != null) {
ajaxActualiza(event, OpcionesAjax.F_FIN);
}
}
// fechaInicioTextChange and fechaInicioClickChange do pretty much the same as these two
private void compareInicioBeforeFin() {
if(fechaInicio.after(fechaFin)) {
fechaFin = fechaMaxFin;
addErrorMessage(FINI_AFTER_FFIN);
}
}
There are two Ajax events because the JSF change event doesn't trigger when you click on the calendar and the PrimeFaces dateSelect doesn't trigger when you type a date in.
I've tried the onSelectUpdate from the calendar and the render and update from both ajax events, setting them to #this, #form, the end date calendar's ID, both calendars' IDs, the calendar's outputPanel's ID and the common outputPanel's ID, and the damn calendars just. Won't Update.
I'm at my wits' end and my Google Fu doesn't find any solution that works either.
You need to set an ajax event on the click of the start date calendar :
<p:calendar id="start_date" pattern="dd/MM/yyyy HH:mm" value="#{managedBean.startDate}" size="20" >
<p:ajax event="dateSelect" listener="#{managedBean.onSelectDate()}" update=":form:end_date" />
</p:calendar>
<p:calendar id="end_date" pattern="dd/MM/yyyy HH:mm" mindate="#{managedBean.startDate}" value="#{managedBean.endDate}" size="20" />
When you select the startDate that triggers a method where you set endDate to null, and you update the endDate calendar, which is limited by mindate="#{managedBean.startDate}"
public void onSelectDate() {
this.setEndDate(null);
}
First of all: f:ajax doesn't have an update attribute, in f:ajax you need to use the render attribute.
A p:remoteCommand with the ajax oncomplete Attribute should solve the problem:
<p:outputPanel id="fl83">
<p:remoteCommand name="updateCalendar" update="fl83" />
<p:outputPanel id="fl83c3">
<h:outputLabel value="Start date" for="fechaInicioMP" />
<p:calendar locale="es" pattern="dd/MM/yyyy" id="fechaInicioMP"
maxdate="#{filtroFechasBB.fechaMaxFin}" value="#{filtroFechasBB.fechaInicio}"
onSelectUpdate=":f183" >
<p:ajax event="blur" />
<f:ajax event="change" listener="#{filtroFechasBB.fechaInicioTextChange}"
oncomplete="updateCalendar()" />
<p:ajax event="dateSelect" listener="#{filtroFechasBB.fechaInicioClickChange}"
oncomplete="updateCalendar()" />
</p:calendar>
</p:outputPanel>
<p:outputPanel id="fl83c4">
<h:outputLabel value="End date" for="fechaFinMP" />
<p:calendar locale="es" pattern="dd/MM/yyyy" id="fechaFinMP"
maxdate="#{filtroFechasBB.fechaMaxFin}" value="#{filtroFechasBB.fechaFin}"
onSelectUpdate="f183" >
<p:ajax event="blur" />
<f:ajax event="change" listener="#{filtroFechasBB.fechaFinTextChange}"
oncomplete="updateCalendar()" />
<p:ajax event="dateSelect" listener="#{filtroFechasBB.fechaFinClickChange}"
oncomplete="updateCalendar()" />
</p:calendar>
</p:outputPanel>
</p:outputPanel>
If that doesn't solve the problem: do you've a form around it which modifies the ids? If you've a without prependId="false" form1 is prepend to every id inside the form. So you'd need to access the panel with exampleForm:fl83.

Trying to fill h:selectOneMenu when date is selected

At this moment my code works but I have to select a date twice if I want to get properly information. I tried to change the ajax event to dateSelect, but it adds an hash in my URL and do nothing. I just want to keep its current behaviour, but selecting a date one single time.
Thanks in advance.
<h:form>
<h:panelGrid columns="2">
<h:outputLabel for="medico" value="Médico:" />
<h:inputText id="medico" value="#{pacienteControlador.pacienteActual.medico.nombre} #{pacienteControlador.pacienteActual.medico.apellidos}" disabled="true"/>
<p:outputLabel for="fecha" value="Fecha:" />
<p:calendar id="fecha" value="#{pacienteControlador.calendarManagedBean.date}" pattern="dd/MM/yyyy">
<f:ajax event="blur" listener="#{pacienteControlador.citasDisponibles()}" render="hora" />
</p:calendar>
<p:outputLabel for="hora" value="Hora:" />
<h:selectOneMenu id="hora" value="#{pacienteControlador.horaCita}">
<f:selectItems value="#{pacienteControlador.listaHorasLibres}" />
</h:selectOneMenu>
</h:panelGrid>
<h:commandButton value="Crear" action="#{pacienteControlador.crearCita()}"/>
</h:form>
Solution:
Use p:ajax instead f:ajax
<p:ajax event="dateSelect" listener="{pacienteControlador.citasDisponibles()}" update="hora" />

JSF selectonemenu does not update

i am beginner in JSF ,i have a problem with selectonemenu item.When i choose the an item ,for example ' FirstLabel',outputpanel should be shown.However ,selectone menu does not update my choice.I use primefaces 3.1 library.How can i solve this problem.Thanks for helps.
<p:selectOneMenu value="#{denemeView.str}" effect="fold" editable="true" >
<f:selectItem itemLabel="Please choose!." itemValue="" />
<f:selectItem itemLabel="FirstLabel" itemValue="1" />
<f:selectItem itemLabel="SecondLabel" itemValue="2" />
<p:ajax process="#this" update=":Form2:panel1"/>
<p:ajax process="#this" update=":Form2:panel2"/>
</p:selectOneMenu>
</p:outputPanel>
<p:outputPanel id="panel1" rendered="#{denemeView.str=='1'}">
<h:outputText value="Output: * " />
<p:inputText id="out" value="#{denemeView.islem}" />
</p:outputPanel>
<p:outputPanel id="panel2" rendered="#{denemeView.str=='2'}">
<h:outputText value="True choice! " />
</p:outputPanel>
If a JSF component has rendered="false" set then it's not redered (the component object is not present in the object tree) and cannot be updated using <p:ajax update="someId"/> or <f:ajax render="someId"/>. What you need to do is wrap these two panels in an outer panel and update that one. Something like this:
<p:ajax process="#this" update="outerPanel"/>
...
<p:outputPanel id="outerPanel">
<p:outputPanel id="panel1" rendered="#{denemeView.str=='1'}">
<h:outputText value="Output: * " />
<p:inputText id="out" value="#{denemeView.islem}" />
</p:outputPanel>
<p:outputPanel id="panel2" rendered="#{denemeView.str=='2'}">
<h:outputText value="True choice! " />
</p:outputPanel>
</p:outputPanel>
See here for a similar problem.

Is conditional rendering of components possible inside datatable without updating the entire datatable?

<h:dataTable value="#{bean.listOfRows}" var="eachRow" id="theDataTable">
<h:column>
<p:outputPanel rendered="#{eachRow.visible}">
<h:selectManyCheckbox
value="#{xxxx}"
label="#{xxxx}">
<f:selectItems value="#{checkBoxItems}" var="eachItem" itemLabel="#{eachItem.label}" itemValue="#{eachItem.value}" />
<p:ajax event="change" update="theDataTable" />
</h:selectManyCheckbox>
</p:outputPanel>
<p:outputPanel rendered="#{eachRow.visible}">
<h:selectOneRadio
value="#{xxxx}"
label="#{xxxx}">
<f:selectItems value="#{radioItems}" var="eachItem" itemLabel="#{eachItem.label}" itemValue="#{eachItem.value}" />
<p:ajax event="change" update="theDataTable" />
</h:selectOneRadio>
</p:outputPanel>
<p:outputPanel rendered="#{eachRow.visible}">
</p:outputPanel>
<p:outputPanel rendered="#{eachRow.visible}">
</p:outputPanel>
<p:outputPanel rendered="#{eachRow.visible}">
</p:outputPanel>
<p:outputPanel rendered="#{eachRow.visible}">
</p:outputPanel>
.
.
.
</h:column>
</h:dataTable>
Within the set of rows of the data table, some rows are to be conditionally rendered depending on the VALUE CHANGE EVENTS(processed using AJAX requests) on the previous row's input component. Can I make these rows visible without re-rendering the entire data table ? ? ?
I am using JSF 2.0.6 with PrimeFaces 2.2.1.
As suggested by BalusC for this question link use padding in the datatable column like this.
<h:dataTable id="mainDatatable" value="#{bean.listOfRows}" var="eachRow" id="theDataTable">
<h:column>
<h:panelGroup id="padding" layout="block">
<p:outputPanel rendered="#{eachRow.visible}">
<h:selectManyCheckbox
value="#{xxxx}"
label="#{xxxx}">
<f:selectItems value="#{checkBoxItems}" var="eachItem" itemLabel="#{eachItem.label}" itemValue="#{eachItem.value}" />
<p:ajax event="change" update="theDataTable" />
</h:selectManyCheckbox>
</p:outputPanel>
<p:outputPanel rendered="#{eachRow.visible}">
<h:selectOneRadio
value="#{xxxx}"
label="#{xxxx}">
<f:selectItems value="#{radioItems}" var="eachItem" itemLabel="#{eachItem.label}" itemValue="#{eachItem.value}" />
<p:ajax event="change" update="theDataTable" />
</h:selectOneRadio>
</p:outputPanel>
<p:outputPanel rendered="#{eachRow.visible}">
</p:outputPanel>
<p:outputPanel rendered="#{eachRow.visible}">
</p:outputPanel>
<p:outputPanel rendered="#{eachRow.visible}">
</p:outputPanel>
<p:outputPanel rendered="#{eachRow.visible}">
</p:outputPanel>
.
.
.
</h:panelGroup>
</h:column>
</h:dataTable>
The datatable creates padding over every component in the column whether rendered or not. Now it is upto your dependent logic. If you want to update particular row of the datatable use the client id generated from a backing bean or binding the component to bean as suggested by BalusC in this question. The client id will be of the format mainDatatable:rowIndex:padding. Cheers!

Resources