如何清除必填字段值 - 恢复为上一个有效值

时间:2015-10-07 07:55:56

标签: validation converter jsf-2.2

我的facelet上有一个输入字段,带有自定义转换器(对于任何其他对象,在我的示例中只是另一个字符串)以及自定义验证器(“必需”值,以及其他检查)。这是一个描述预期的用例,以及有问题的实际步骤:

  1. 输入有效值和模糊字段(制表符或单击其他元素)。
    • 转换器将字段值更改为对象的规范化字符串表示形式。 如预期
  2. 返回并输入无效值,再次模糊。
    • 验证消息显示错误。 如预期
    • 字段值保持无效值。 如预期
  3. 返回并删除值,再次模糊。
    • 验证消息显示错误。 如预期
    • 字段值更改回上一个有效(标准化)值。 没有预期,希望它保持空白
  4. 如果验证消息显示应提供值,而旧的有效值显示,则有点违反直觉。我知道如果验证失败,我可以做些什么来保持字段清晰?

    我可能需要强调关于转换器的以下内容:

    • null /空字符串将转换为null对象。 (但验证器需要有效的非空值。)
    • blur上的ajax调用用于在键入值时始终运行转换器 - 意图是将提供的值转换为支持bean成员的对象,然后转换回( “normalized”)对象的字符串表示。 (“规范化”示例:符合枚举常量名称的大小写,或者处于特定日期格式。)

    我在GlassFish 4.1上使用JSF 2.2(Mojarra 2.2.7)。

    示例代码(仅仅显示一个测试用例,但包含重要部分 - 我认为):

    支持bean:

    @ManagedBean
    @ViewScoped
    public class TestBean implements Serializable {
        :
        private String test; // plus g/setters
        :
    }
    

    JSF查看页面:

    <h:form>
        :
        <h:inputText id="test" binding="#{test}" value="#{testBean.test}">
            <cp:uppercaseConverter />
            <f:validator binding="${testValidator}" />
            <f:ajax event="blur" render="@this msg_test" /><!-- @this forces converter on blur -->
        </h:inputText>
        <h:messages id="msg_test" for="test" />
        :
    </h:form>
    

    自定义转换器(请记住,出于测试目的,有点人为)

    /**
     * The "object" as used in the backing bean is simply the uppercase version of
     * the input value in the field.
     */
    @FacesConverter("UppercaseConverter")
    public class UppercaseConverter implements Converter, Serializable {
        private static final long serialVersionUID = 1L;
    
        @Override
        public Object getAsObject(
            FacesContext ctx, UIComponent component, String newValue
        ) throws ConverterException {
            if (newValue == null || newValue.trim().equals(""))
                return null;
            return newValue.toUpperCase();
        }
    
        @Override
        public String getAsString(
            FacesContext ctx, UIComponent component, Object value
        ) throws ConverterException {
            if (value == null) return "";
            return value.toString();
        }
    }
    

    自定义验证器:(请记住,出于测试目的,有点人为)

    /**
     * Values are valid only if they start with an "A" (not case sensitive).
     * Thus, null or empty values are also invalid implicitly.
     */
    @ManagedBean
    @FacesValidator
    public class TestValidator implements Validator {
    
        @Override
        public void validate(
            FacesContext context, UIComponent component, Object value
        ) throws ValidatorException {
            if (value == null || !value.toString().trim().toLowerCase().startsWith("a"))
                throw new ValidatorException(new FacesMessage("A value starting with A or a is required"));
        }
    }
    

1 个答案:

答案 0 :(得分:0)

问题显然是由<f:ajax>调用render s @this以及消息元素引起的。

渲染@this会导致转换器运行并在字段中显示转换后的值(但显然无法对无效值或空值执行此操作)。

我认为目前最简单的解决方法是从@this属性中删除render。结果将只有一个轻微的美学缺陷,这不是世界末日 - 在我看来更不严重(使用户感到困惑),而不是在有效且先前输入和覆盖的值上显示“此无效”消息。 / p>