【问题标题】:How to submit a form with disabled input that got a conversion error如何提交带有禁用输入且出现转换错误的表单
【发布时间】:2013-10-15 08:48:10
【问题描述】:

我有以下页面/bean 结构(使用 myfaces 2.0.11 + tomcat 6)

我有一个复选框,当检查 h:inputtext(我的bean中的 Integer variable中连接到 h:inputtext)旁边是启用了他的旁边,并且当未选中复选框时,输入是禁用的,我有一个提交按钮将它们都提交(整个表单)

这里是代码

<h:form prependId="false">
    <h:selectBooleanCheckbox id="my_len" value="#{myBean.myLenBool}">
        <f:ajax render="my_len_input_wrapper"/>
    </h:selectBooleanCheckbox>
    <h:panelGroup id="my_len_input_wrapper">
        <h:inputText value="#{myBean.myLen}" id="my_len_input"
            disabled="#{not myBean.myLenBool}" required="#{myBean.myLenBool}">
            <f:validateLongRange minimum="1"/>
        </h:inputText>
        <h:message for="my_len_input"/>
    </h:panelGroup> 

        <h:commandButton action="#{myBean.submit}" value="submit">
            <f:ajax render="@form" execute="@form"></f:ajax>
        </h:commandButton>
</h:form>

豆码

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class myBean {
    Integer myLen;
    boolean myLenBool;

    public Integer getMyLen() {
        return myLen;
    }

    public void setMyLen(Integer myLen) {
        this.myLen = myLen;
    }

    public boolean isMyLenBool() {
        return myLenBool;
    }

    public void setMyLenBool(boolean myLenBool) {
        this.myLenBool = myLenBool;
    }

    public void submit() {
        // submit
    }

}

场景如下

1) 选中复选框(将启用输入) 2)输入一个无效值(例如0.5),其无效原因myLenInteger 3) 点击提交 -> 错误信息将显示在h:message 导致转换错误的原因 4)取消选中复选框(它将禁用输入文本) 5)点击提交

所以问题是:如何提交带有禁用输入且出现转换错误的表单???

到目前为止,我发现的唯一解决方案是编写我自己的自定义 converter,如果该字段被禁用,它将忽略转换

@FacesConverter("APCustomConverter")
public class APCustomConverter extends IntegerConverter{

    @Override
    public Object getAsObject(FacesContext context, UIComponent component, String value) {

        if (component.getAttributes().get("disabled") != null && component.getAttributes().get("disabled").equals(true)) {
            return null;
        }
        Object retValue = super.getAsObject(context, component, value);
        return retValue;
    }
}

希望有比我更好的解决方案(使用CustomConverter),

有点离题/不太离题:

这个转换错误最终导致我遇到了一个非常烦人的场景:当我使用只有 render="@form" 的丢弃按钮时,复选框的状态和输入错误,以至于在单击丢弃后 -> 复选框保持选中状态(虽然它不应该导致表单没有真正提交)并且输入被禁用而不是只读导致真正的复选框值为假,并且当我再次点击提交时,复选框被真正选中,但输入让自己为空值(所有这些都会导致服务器上出现空指针异常),所以最终我不得不在丢弃按钮中使用&lt;f:actionListener type="org.omnifaces.eventlistener.ResetInputAjaxActionListener" /&gt; by omnifaces

【问题讨论】:

    标签: jsf-2


    【解决方案1】:

    使用 Mojarra 2.1.26MyFaces 2.0.11 进行测试。取消选中该复选框时,Mojarra 会更新 h:inputText 并将其留空,这是预期的行为,因为该值从未达到模型(验证错误)。但是,MyFaces 仅将其更新为禁用模式,将旧的输入值保留在那里。

    这似乎是一个 MyFaces 问题,即使在最新的 (2.1.12-2.0.18) 分支版本中也没有解决。实际上,如果您想根据其状态跳过某些元素的转换/验证,那么编写自定义转换器/验证器是可行的方法,但在您的情况下,问题与 MyFaces 的 ajax 周期有关,它应该像 Mojarra 的那样工作可以。

    作为一种解决方案,您有三种可能的选择:

    • 如果可能,切换到 Mojarra 实施,这将使问题消失。
    • 编写一些 JS 代码,以便在取消选中复选框时重置输入值。
    • 使用您当前的解决方案,在被禁用的情况下跳过服务器端的元素转换。

    【讨论】:

    • 谢谢,我猜你的意思是在你的回答中使用 conversion 词而不是 validation ......因为它是一个 conversion 阻止表单提交的错误,我仍然想知道是否有更好的解决方案而不是自定义Converter
    • 谢谢,我已经重写了我的答案,因为它对转换和验证阶段都有效。另外我会为您添加一些可能的解决方法!
    猜你喜欢
    • 1970-01-01
    • 2015-11-16
    • 2012-02-08
    • 1970-01-01
    • 2011-02-14
    • 2013-05-19
    • 1970-01-01
    • 2018-07-27
    相关资源
    最近更新 更多