Disable one input when other input is filled out - jsf

I want to disable other input tag if p:calendar value is entered
<p:calendar id="someDate" value=.... binding="#{bind}" />
for example to disable p:selectOneMenu but this disables it permanently.
<p:selectOneMenu id="selectManu" value=... disabled="#{bind!=null}" >
How to disable it only if p:calendar have value ??

Let the source component ajax-update the target component on the desired events, and let the disabled attribute of the target component check if the value of the source component is not empty.
So,
<p:calendar ... value="#{bean.date}">
<p:ajax event="valueChange" update="menu" />
<p:ajax event="dateSelect" update="menu" />
</p:calendar>
...
<p:selectOneMenu id="menu" ... disabled="#{not empty bean.date}" />
The binding is not necessary in this construct. If you really want to use it, then you should be checking the component's value attribute, not the component itself (which is obviously never null).
<p:calendar binding="#{calendar}" ...>
<p:ajax event="valueChange" update="menu" />
<p:ajax event="dateSelect" update="menu" />
</p:calendar>
...
<p:selectOneMenu id="menu" ... disabled="#{not empty calendar.value}" />
If you want to learn more about binding, head to How does the 'binding' attribute work in JSF? When and how should it be used?

Related

Update Component Even If SelectOneMenu Value Is Required

I have a required select and my problem is that when the user selects an empty option (null) the validation jumps in and the listener call of the select is being skipped. Some components on my view are depending on this value so in case of null being selected the bean won't get actualized and the components don't change.
Example:
<h:form id="createForm">
<p:selectOneMenu id="produktCreateTypSelect"
converter="omnifaces.SelectItemsIndexConverter"
value="#{productController.selectedProduct.typ}" required="true">
<f:selectItem itemValue="#{null}" itemLabel="-- Select --" />
<f:selectItems var="productType" value="#{productController.findAllProducts()}"
itemLabel="#{productType.name}" itemValue="#{productType}" />
<p:ajax process="#this " event="valueChange" update="createForm"
listener="#{productController.printHelloWorld}" />
</p:selectOneMenu>
<h:panelGroup id="dummy1" rendered="#{productController.selectedProduct.type != null}" />
</h:form>
The question is what the best way is to update that panelGroup
'dummy1'
Thanks for any help.

Ajax event change doesn't work

I've a form, and i want it to show some inputs only if the user mark yes on a selectOneRadio.
Here is the code:
<p:selectOneRadio id="someSelectRadio" value="#{someBean.someClass.someSelectRadio}" >
<f:selectItem itemLabel="Sim" itemValue="Sim" />
<f:selectItem itemLabel="Não" itemValue="Não" />
//Here i use event=change to reconize if the user mark a option on selectOneRadio
<p:ajax event="change" process="someSelectRadio" update="panelGeral" />
</p:selectOneRadio>
//Here is the panel that i want to appear if the user mark selectOneRadio
<p:outputPanel id="panelGeral">
<p:panel id="panel" autoUpdate="true" rendered="#{someBean.someClass.someMethod}" />
</p:outputPanel>
I already have tryied to change event do click, on click, both doesn't work for me.
This may be due to the problem with event .
Change to
<p:ajax event="valueChange" process="someSelectRadio" update="panelGeral" />
More info

Conditionally render depend on p:selectOneMenu value

I'm trying to build a custom component from existing Primefaces components and I need some help here. I have a selectOneMenu and I want it to render or not (and disable or enable) other components according to which option is selected in the menu. The hard thing here is that I can't do it using a Managed Bean (I have a few reasons for that), I need a pure xhtml code.
I tried some <c:choose> and <ui:parameter> stuff to create booleans but for some reason that I can't see it's not working. Could you guys take a look at my code and see if you have any ideas? It may be something simple that I can't figure or something I don't know yet.
<h:body>
<h:form id="abc">
<ui:repeat var="pd" value="#{produtoMB.produtos}">
<h:panelGroup id="linha">
<c:choose>
<c:when test="#{pd.marca == X1}">
<c:set var="render" value="#{true}" />
</c:when>
<c:otherwise>
<c:set var="render" value="#{false}" />
</c:otherwise>
</c:choose>
<p:selectOneMenu value="#{pd.marca}">
<f:selectItem itemLabel="Select One" itemValue="" noSelectionOption="true"/>
<f:selectItem itemLabel="Xbox One" itemValue="X1" />
<f:selectItem itemLabel="PlayStation 4" itemValue="PS4" />
<f:selectItem itemLabel="Wii U" itemValue="WU" />
<p:ajax update="linha" />
</p:selectOneMenu>
<p:inputText value="#{pd.aparelho}" disabled="#{render}"/>
<h:outputText value="Microsoft" rendered="#{render}"/>
<p:commandButton value="X" />
</h:panelGroup>
<br />
</ui:repeat>
<br />
<p:commandButton actionListener="#{produtoMB.botaoMais}" value="+" update="abc"/>
<p:commandButton actionListener="#{produtoMB.botaoMenos}" value="-" update="abc"/>
</h:form>
There are a couple of issues here.
First,
<ui:repeat ...>
<c:choose>
...
</c:choose>
</ui:repeat>
JSTL tags run during view build time. It's executed only once before all JSF component runs. So, on contrary to what you'd intuitively expect from the XML code flow, it isn't executed when the <ui:repeat> component runs and iterates. See also JSTL in JSF2 Facelets... makes sense?
Second,
<c:when test="#{pd.marca == X1}">
...
<f:selectItem ... itemValue="X1" />
The itemValue="X1" represents a String. The EL expression #{X1} basically looks for a variable named X1 in respectively the facelet, request, view, session, and application scopes until the first non-null value is found. In order to represent a String value in EL, you need to quote it with singlequotes like so #{'X1'}. So, you should have used #{pd.marca == 'X1'} instead. Nonetheless, this still won't work for the reason mentioned in the first point. See also Specify conditional rendering of element inside <ui:repeat>? The <c:if> does not seem to work.
You can however use <c:set> to create an alias in the EL scope, as long as you don't set its scope attribute. See also Defining and reusing an EL variable in JSF page.
After removing JSTL <c:choose> and fixing the EL expression #{X1} to represent a real String literal #{'X1'}, here's how it should look like:
<ui:repeat var="pd" value="#{produtoMB.produtos}">
<p:selectOneMenu value="#{pd.marca}">
<f:selectItem itemLabel="Select One" itemValue="#{null}" />
<f:selectItem itemLabel="Xbox One" itemValue="X1" />
<f:selectItem itemLabel="PlayStation 4" itemValue="PS4" />
<f:selectItem itemLabel="Wii U" itemValue="WU" />
<p:ajax update="linha" />
</p:selectOneMenu>
<h:panelGroup id="linha">
<c:set var="marcaIsX1" value="#{pd.marca eq 'X1'}" />
<p:inputText value="#{pd.aparelho}" disabled="#{marcaIsX1}" />
<h:outputText value="Microsoft" rendered="#{marcaIsX1}" />
</h:panelGroup>
<p:commandButton value="X" />
</ui:repeat>
Note that I also removed the unused noSelectionOption="true" and moved the <h:panelGroup id="linha"> to wrap only the components which really need to be updated.

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 Inplace - Save Value in focusOut

I need to save values on Focus out in Inplace JSF. Currently the editor tag can be used but it will display a save/cancel button.
My requirement is to save the data on focus out.
This is the Inplace tag that i am using.
<p:inplace id="basic">
<p:inputText value="Edit Me" />
</p:inplace>
Is there any ajax event like.
<p:ajax event="Something like focusOut" listener="#{bean.myFunction()}"/>
My Code sample when i use Blur as ajax event
<p:inplace label="#{serviceCalendarViewManagedBean.selectedService.statusStr}" id="ajaxInplaceStatusEdit" >
<p:ajax event="blur" listener="#{serviceCalendarViewManagedBean.inplaceEdit('StatusEdit')}" update="view" oncomplete="scheduleWidget.update();"/>
<p:selectOneMenu id="statusEditImplace" required="true"
value="#{serviceCalendarViewManagedBean.selectedService.status}"
label="text">
<f:selectItems value="#{serviceCalendarViewManagedBean.serviceStatusList}"
var="status" itemLabel="#{status.title}" itemValue="#{status.id}" />
</p:selectOneMenu>
</p:inplace>
The error message That i get when using this event
/WEB-INF/views/service/servicecalendarview.xhtml #886,153 <p:ajax>
Event:blur is not supported.
You're looking for the onblur event:
Execute a JavaScript when a user leaves an input field:
JSF code:
<p:ajax event="blur" listener="#{bean.myFunction()}"/>
EDIT: from your posted code, the <p:ajax> affects the <p:inplace> where it should affect the <p:selectOneMenu>. Move the <p:ajax> inside the <p:selectOneMenu>:
<p:inplace label="#{serviceCalendarViewManagedBean.selectedService.statusStr}"
id="ajaxInplaceStatusEdit" >
<p:selectOneMenu id="statusEditImplace" required="true"
value="#{serviceCalendarViewManagedBean.selectedService.status}"
label="text">
<f:selectItems value="#{serviceCalendarViewManagedBean.serviceStatusList}"
var="status" itemLabel="#{status.title}" itemValue="#{status.id}" />
<p:ajax event="blur" listener="#{serviceCalendarViewManagedBean.inplaceEdit('StatusEdit')}"
update="view" oncomplete="scheduleWidget.update();"/>
</p:selectOneMenu>
</p:inplace>

Resources