I'm trying to do the following: When the user enters a value in the rich:calendar
component, then the h:inputText
should have its required
attributed set to true
. I'm following the instructions in this post: Reference JSF control's attributes via JavaScript
Sorry for creating another post, but I couldn't figure out how to post the code into the comments area and make it readable. The page throws this error:
javax.el.ELException: /pages/overtime/overtime-n.xhtml @121,65 binding="#{oc.overtimeDate}": java.lang.IllegalArgumentException: argument type mismatch
The problem is that the binding is inside a c:forEach
loop, and I'm trying to use the loop variable to bind to. The overtime.overtimeItems
is defined as an ArrayList<OvertimeComponent>
with each OvertimeComponent object having various properties (overtimeDate
, overtimeDateId
, id
, overtimeHours
, etc.).
<c:forEach items="#{overtime.overtimeItems}" var="oc">
<rich:calendar value="#{oc.overtimeDate}"
requiredMessage="Date 1 is required."
id="#{oc.overtimeDateId}"
binding="#{oc.overtimeDate}"
required="#{oc.id == 1 ? true : false}">
</rich:calendar>
<h:inputText value="#{oc.overtimeHours}"
id="#{oc.overtimeHoursId}"
requiredMessage="Hours is required."
required="#{not empty oc.overtimeDate.value}" >
</h:inputText>
.....
</c:forEach>
How do I make the h:inputText
required if the rich:calendar
object has a value? There's a way to do this using the binding
property of the calendar, but I'm not sure how to do it inside a c:forEach
. I can't use AJAX for this project. Thanks.
The binding
attribute should point to an UIComponent
, not to a value object like Date
. The answer in your previous question would have worked if you wasn't using c:forEach
.
<rich:calendar value="#{oc.overtimeDate}"
requiredMessage="Date 1 is required."
id="#{oc.overtimeDateId}"
binding="#{calendarComponent}"
required="#{oc.id == 1 ? true : false}">
</rich:calendar>
<h:inputText value="#{oc.overtimeHours}"
id="#{oc.overtimeHoursId}"
requiredMessage="Hours is required."
required="#{not empty calendarComponent.value}" >
</h:inputText>
The above example binds the component to the "page scope", not to a particular bean since you're usually not interested in the component from inside the bean. You can name #{calendarComponent}
whatever you want. You can access it anywhere in the same page by the same name.
However, in your particular case you're using c:forEach
and not ui:repeat
, so components are actually repeated in the component tree (the ui:repeat
only repeats in the HTML renderer). This means that you cannot use the suggested approach. All components would then share the same binding which is wrong. Best would be to add an UIComponent
(more precise, UIInput
) property to the object behind oc
and bind to it instead, so that every component has its own unique binding. E.g.
public class OvertimeComponent {
private UIInput calendarComponent;
// ...
with
<rich:calendar value="#{oc.overtimeDate}"
requiredMessage="Date 1 is required."
id="#{oc.overtimeDateId}"
binding="#{oc.calendarComponent}"
required="#{oc.id == 1}">
</rich:calendar>
<h:inputText value="#{oc.overtimeHours}"
id="#{oc.overtimeHoursId}"
requiredMessage="Hours is required."
required="#{not empty oc.calendarComponent.value}" >
</h:inputText>
(note that I simplified the EL of the required
attribute of rich:calendar
since it already returns a boolean
anyway)