简体   繁体   English

JSF 1.2空 <h:selectManyListbox /> 验证问题

[英]JSF 1.2 empty <h:selectManyListbox /> validation issue

I'm kind of new to JSF and I'm having trouble to understand what values JSF renders in a form after its validation fails. 我是JSF的新手,我很难理解JSF验证失败后在表单中呈现的值。 Im using WebSphere 7 and its default implementation of JSF, MyFaces (I think 2.0). 我正在使用WebSphere 7及其默认的JSF实现MyFaces(我认为是2.0)。

My xhtml looks like this: 我的xhtml看起来像这样:

<h:form id="form">
    <h:inputText id="text" value="#{backing.text}" required="true"/>
    <h:message for="text" />

    <h:selectManyListbox id="options" value="#{backing.options}" required="true">
        <f:selectItem itemLabel="1" itemValue="1" />
        <f:selectItem itemLabel="2" itemValue="2" />
        <f:selectItem itemLabel="3" itemValue="3" />
    </h:selectManyListbox>
    <h:message for="options" />

    <h:commandButton value="Save" />
</h:form>

And my backing bean like this: 而我的后备豆是这样的:

public class Backing {

    private String text;

    private String[] options;

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String[] getOptions() {
        return options;
    }

    public void setOptions(String[] options) {
        this.options = options;
    }
}
  1. I fill the <h:inputText /> with some text. 我用一些文本填充<h:inputText />
  2. I select two options from the <h:selectManyListbox /> 我从<h:selectManyListbox />选择两个选项
  3. I press the 'Save' button 我按“保存”按钮
  4. The form is rendered with the value I entered for <h:inputText /> and with the options I selected on the <h:selectManyListbox /> (no validation messages are shown, as expected) 使用我为<h:inputText />输入的值以及在<h:selectManyListbox />上选择的选项来呈现表单(不显示验证消息,这与预期的一样)
  5. Now ... 现在...
  6. I empty the <h:inputText /> 我清空<h:inputText />
  7. I deselect the two options from the <h:selectManyListbox /> 我从<h:selectManyListbox />取消选择两个选项
  8. I press the 'Save' button 我按“保存”按钮
  9. The form renders the <h:inputText /> empty and the <h:selectManyListbox /> with the previous options I had selected (both validation messages are shown, as expected) 该表单将<h:inputText />呈现为空,将<h:selectManyListbox />呈现为具有我选择的先前选项(如预期那样,均显示了验证消息)

As you can see, the behaviour when rendering the <h:inputText /> and the <h:selectManyListbox /> is different: 如您所见,呈现<h:inputText /><h:selectManyListbox />是不同的:

  • <h:inputText /> renders component's submitted value <h:inputText />呈现组件的提交值
  • <h:selectManyListbox /> renders bean's value <h:selectManyListbox />呈现bean的值

I've been trying to render <h:selectManyListbox /> with no options selected without hacking or messing my code, but had no luck. 我一直在尝试渲染<h:selectManyListbox /> ,没有选择任何选项,而不会破坏或弄乱我的代码,但是没有运气。

¿Is this some bug? 这是一些错误吗? ¿Am I missing something? 我错过了什么吗?

The less hacky solution I found is to copy and re-implement the method renderOption , overriding the default MenuRenderer . 我发现的较简单的解决方案是复制并重新实现renderOption方法,从而覆盖默认的MenuRenderer

The original source is something like this as I had to decompile (version 1.2_13). 我不得不反编译(版本1.2_13),原始源是这样的。 Notice that I'm pasting only the lines that actually need to be changed. 注意,我仅粘贴实际需要更改的行。 If you need to use this solution you will have to copy the full contents of the method : 如果您需要使用此解决方案,则必须复制该方法的全部内容

public class MenuRenderer extends HtmlBasicInputRenderer {
    protected void renderOption(FacesContext context, UIComponent component, Converter converter, SelectItem curItem, Object currentSelections, Object[] submittedValues, HtmlBasicRenderer.OptionComponentInfo optionInfo) throws IOException {
        (...)
        Object valuesArray;
        Object itemValue;
        if (submittedValues != null) {
            boolean containsValue = containsaValue(submittedValues);
            if (containsValue) {
                valuesArray = submittedValues;
                itemValue = valueString;
            } else {
                valuesArray = currentSelections;
                itemValue = curItem.getValue();
            }
        } else {
            valuesArray = currentSelections;
            itemValue = curItem.getValue();
        }
        (...)
    }
}

I created CustomListboxRenderer ( ListboxRenderer extends MenuRenderer ) like this: 我创建了CustomListboxRendererListboxRenderer扩展了MenuRenderer ),如下所示:

public class CustomListboxRenderer extends ListboxRenderer {
    @Override
    protected void renderOption(FacesContext context, UIComponent component, Converter converter, SelectItem curItem, Object currentSelections, Object[] submittedValues, HtmlBasicRenderer.OptionComponentInfo optionInfo) throws IOException {
        (...)
        Object valuesArray;
        Object itemValue;
        if (submittedValues != null) {
            valuesArray = submittedValues;
            itemValue = valueString;
        } else {
            valuesArray = currentSelections;
            itemValue = curItem.getValue();
        }
        (...)
    }
}

and then added in faces-config the next lines: 然后在faces-config中添加以下几行:

<render-kit>
    <renderer>
        <component-family>javax.faces.SelectMany</component-family>
        <renderer-type>javax.faces.Listbox</renderer-type>
        <renderer-class>CustomListboxRenderer</renderer-class>
    </renderer>
</render-kit>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM