Reputation: 275
Is it possible to fill the value of required
attribute with boolean EL expression?
I have a form in which Quantity input (qtyInput
) is required only if Description input (descInput
) is not empty. I tried to do it like this:
<h:form id="form">
<p:dataTable var="item" value="#{someController.list}" id="table">
<p:column>
<f:facet name="header" >
<h:outputText value="Description"/>
</f:facet>
<p:inputText value="#item.description}" id="descInput" />
<p:message for="descInput" />
</p:column>
<p:column>
<f:facet name="header" >
<h:outputText value="Quantity"/>
</f:facet>
<p:inputText value="#{item.quantity}" required="#{not empty item.description}" id="qtyInput"/>
<p:message for="qtyInput" />
</p:column>
</p:dataTable>
<p:commandButton id="saveButton" value="Save" action="#{someController.save()}"/>
</h:form>
but it didn't work. Is it possible to do this only with EL, or should I implement custom Validator?
Upvotes: 1
Views: 796
Reputation: 236
An alternative to what BalusC wrote would be to use PrimeFaces p:ajax
<p:inputText ...id="itemDescription" value="#{item.description}">
<p:ajax event="blur" partialSubmit="true" update="itemQuantity" />
</input>
<p:inputText ...id="itemQuantity" value="#{item.quantity}" required="#{not empty item.description}" />
It looks in my opinion elegant, and the only downside would be that whatever was inputted in itemQuantity, it will be reset to beans' value (or no-value if that's the case) after the modification of itemDescription. Also maybe you could use BalusC's library omnifaces which provides some validateAllOrNone validator, although I've never used that yet.
Eduard
Upvotes: 0
Reputation: 1109532
Yes, it is possible. Your problem is just caused by wrong timing. In your current attempt,
<p:inputText ... value="#{item.description}" />
<p:inputText ... value="#{item.quantity}" required="#{not empty item.description}" />
the #{item.description}
is only set during update model values phase, while the required
attribute is evaluated during validations phase, which is one phase before. You're thus checking a value which is not available yet at that moment.
You need to check component's value instead of the model value. You can get it by binding the component to the view and then accessing UIInput#getValue()
.
<p:inputText ... binding="#{descComponent}" value="#{item.description}" />
<p:inputText ... value="#{item.quantity}" required="#{not empty descComponent.value}" />
Note that the components are processed in the order they appear in the component tree, so if you have the above components the other way round, then it would have failed as well. You'd need to check the component's submitted value by UIInput#getSubmittedValue()
instead.
<p:inputText ... value="#{item.quantity}" required="#{not empty descComponent.submittedValue}" />
<p:inputText ... binding="#{descComponent}" value="#{item.description}" />
Upvotes: 1