Note that there are some explanatory texts on larger screens.

plurals
  1. POJSF2 disabled attribute for validator evaluated only for first cycle?
    primarykey
    data
    text
    <p>I found that disabled attribute for any validator I use in JSF2 is evaluated only in the first cycle if my managed bean is ViewScoped.</p> <p>But I would like to make use of <em>disabled</em> attribute for my validators based on data I get from 4th update phase. So I would expect it reevaluated in all cycles performed on the same view.</p> <p>Example xhtml page:</p> <pre><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt; &lt;html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"&gt; &lt;h:head&gt;&lt;/h:head&gt; &lt;h:body&gt; &lt;h:form&gt; &lt;h:panelGrid id="pnlGrid"&gt; &lt;h:inputText id="someValueId" value="#{testPageBean.someValue}"&gt; &lt;f:validateLength minimum="2" maximum="4" disabled="#{testPageBean.disableValidateLength}"/&gt; &lt;/h:inputText&gt; &lt;h:messages for="someValueId"/&gt; &lt;h:commandButton action="#{testPageBean.doSomething}" value="Do something" /&gt; &lt;/h:panelGrid&gt; &lt;/h:form&gt; &lt;/h:body&gt; &lt;/html&gt; </code></pre> <p>and its <strong>view scoped</strong> managed bean</p> <pre><code>package cz.kamosh; import java.io.Serializable; import javax.faces.bean.ManagedBean; import javax.faces.bean.ViewScoped; @ManagedBean @ViewScoped public class TestPageBean implements Serializable { boolean disableValidateLength = false; private String someValue; public TestPageBean() { System.out.println("Constructor TestPageBean"); } public String getSomeValue() { return someValue; } public void setSomeValue(String someValue) { this.someValue = someValue; } /** * Some action without any navigation as a result */ public void doSomething() { disableValidateLength = !disableValidateLength; System.out.printf( "DoSomething, someValue: %1$s, disableValidateLength: %2$b\n", someValue, disableValidateLength); } public boolean isDisableValidateLength() { System.out.printf("IsValidateLength, disableValidateLength: %1$b\n", disableValidateLength); return disableValidateLength; } } </code></pre> <p>I know that I should blame implementation <em>com.sun.faces.facelets.tag.jsf.ValidatorTagHandlerDelegateImpl</em>: </p> <pre><code>private void applyNested(FaceletContext ctx, UIComponent parent) { // only process if it's been created if (!ComponentHandler.isNew(parent)) { return; } ... } </code></pre> <p>These three rows cause validator not being reevaluated its <em>disabled</em> attribute when I perform action:-(</p> <p>Could some please give me a hint, what was the motivation for JSF2 guys to implement this way or even better how to solve my problem?</p> <p><strong><em>EDIT:</em></strong></p> <p>Version of JSF2: <em>2.0.3-SNAPSHOT</em></p> <p>web.xml:</p> <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"&gt; &lt;display-name&gt;JSF2Testing&lt;/display-name&gt; &lt;servlet&gt; &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt; &lt;servlet-class&gt;javax.faces.webapp.FacesServlet&lt;/servlet-class&gt; &lt;load-on-startup&gt;1&lt;/load-on-startup&gt; &lt;/servlet&gt; &lt;servlet-mapping&gt; &lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt; &lt;url-pattern&gt;/faces/*&lt;/url-pattern&gt; &lt;/servlet-mapping&gt; &lt;context-param&gt; &lt;param-name&gt;javax.faces.PARTIAL_STATE_SAVING&lt;/param-name&gt; &lt;param-value&gt;false&lt;/param-value&gt; &lt;/context-param&gt; &lt;/web-app&gt; </code></pre> <p><HR></p> <p><strong><em>EDIT2</em></strong> Attempt to follow <a href="https://stackoverflow.com/questions/7445417/why-does-fvalidatedoublerange-only-work-for-sessionscoped">BalusC' suggestion</a></p> <p>Changes on page:</p> <pre><code>&lt;h:inputText id="someValueId" value="#{testPageBean.someValue}"&gt; &lt;f:validator validatorId="myLengthValidator"/&gt; &lt;f:attribute name="disableMyLengthValidator" value="#{testPageBean.disableValidateLength}"/&gt; &lt;f:attribute name="minimum" value="2" /&gt; &lt;f:attribute name="maximum" value="4" /&gt; &lt;/h:inputText&gt; </code></pre> <p>Own validator used instead of standard <strong></strong>:</p> <pre><code>import java.io.Serializable; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.validator.FacesValidator; import javax.faces.validator.LengthValidator; import javax.faces.validator.ValidatorException; @FacesValidator("myLengthValidator") public class MyLengthValidator extends LengthValidator implements Serializable { public MyLengthValidator() { System.out.println("MyLengthValidator constructor"); } @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { if((Boolean)component.getAttributes().get("disableMyLengthValidator")) { return; } setMinimum(Integer.valueOf((String)component.getAttributes().get("minimum"))); setMaximum(Integer.valueOf((String)component.getAttributes().get("maximum"))); super.validate(context, component, value); } } </code></pre> <p>My notes about this solution:</p> <ul> <li>requires own implementation even if for standard validators</li> <li>is dependent on attributes on component (inputText) level</li> <li>validator is triggered even if it should not be</li> <li>I am pretty sure it will not behave as we expect when client side validation is provided for validator</li> <li>I consider is as very ugly and not following JSF2 :-(</li> </ul>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload