1

我有一个包含多个组件的表单,其中一些有自己的验证和/或是强制性的。然后我还有几个selectOneMenu组件在它们的列表中具有相同的三个selectItem元素。我已经定义了三个commandButton,以便为所有列表选择相同的值(commandButton每个可能值一个)。

JSF 部分

<table>
    <tr>
        <td>
            <h:outputText value="ID:" />
        </td>
        <td>
            <h:inputText value="#{MyClass.id}" id="inTxt_id" required="true">
                <f:validator validatorId="CheckIDPattern" />
            </h:inpuText>
            <h:message for="inTxt_id" errorClass="error" />
        </td>
    </tr>
</table>
<table>
    <tr>
        <td>
            <h:commandButton value="Select all opt1" action="#{MyClass.selectOpt1}" />
            <h:commandButton value="Select all opt2" action="#{MyClass.selectOpt2}" />
            <h:commandButton value="Select all opt3" action="#{MyClass.selectOpt3}" />
        </td>
    </tr>
    <tr>
        <td>
            <h:outputText value="List 1:" />
        </td>
        <td>
            <h:selectOneMenu value="#{MyClass.list1Val}">
                <f:selectItems value="#{MyClass.listOfOptions}" />
            </h:selectOneMenu>
        </td>
    <tr>
        <td>
            <h:outputText value="List 2:" />
        </td>
        <td>
            <h:selectOneMenu value="#{MyClass.list2Val}">
                <f:selectItems value="#{MyClass.listOfOptions}" />
            </h:selectOneMenu>
        </td>
    </tr>
    <tr>
         //Many other selectOneMenu components...
    </tr>
</table>
<h:commandButton action="#{MyClass.saveLists}" value="Submit" />

MyClass.java

public String selectOpt1(){
    this.list1Val = 1;
    this.list2Val = 1;
    //...
    return "";
}

//The same idea for selectOpt2 and selectOpt3.

在这种情况下,如果我的用户按下我的“全选”按钮之一而不填写 ID inputText,它会收到错误消息,但我不想要它,因为我想他们还没有完成填写表格。我只想在用户按下“保存列表”按钮时执行验证。

我尝试添加immediate="true"到我的“全选”按钮,它可以工作,但它不会从模型更新视图,然后用户看不到值已经改变......所以它真的不起作用。

我想达到什么目标?我只想在最后一个按钮(提交)时执行验证。因此,我的用户可以使用这些“全选”按钮,而无需预先填写强制性组件。

我希望你能理解我的上下文。随时要求任何澄清。提前致谢。

4

3 回答 3

2

如果您使用的是@ViewScopedbean,则可以进行以下更改:

首先将您的selectOpt1方法更改为键入void

public void selectOpt1() 
{
    this.list1Val = 1;
    this.list2Val = 1;
    //...
}

在选择项目时给id要更新的组件。在这种情况下,我假设列表 1:

<h:selectOneMenu id="list1" value="#{MyClass.list1Val}">
    //...
</h:selectOneMenu>

在您的按钮中,添加一个f:ajax仅部分提交该组件进行处理的标签:

<h:commandButton value="Select all opt1" action="#{MyClass.selectOpt1}">
    <f:ajax execute="@this" render="list1" />
</h:commandButton>

如果您计划更新多个组件,您可以添加它们的 id,以空格分隔:

<f:ajax execute="@this" render="list1 list2" />

我希望它有所帮助。

编辑

好吧,抱歉,我没有注意到您使用的是 JSF 1.x。在这种情况下,它不起作用。

不过,您可以使用RichFaces之类的库来添加 ajax 功能。请查看以下主题:

富脸

正如您提到的,您正在使用 RichFaces,您可以将f:ajax标签切换为a4j:support

<h:commandButton value="Select all opt1" action="#{MyClass.selectOpt1}">
    <a4j:support event="onclick" reRender=":list1" ajaxSingle="true" />
</h:commandButton>

或者像这样使用a4j:commandButton

<a4j:commandButton value="Select all opt1" reRender=":list1" ajaxSingle="true" />

有关此行为的更多信息,请查看.

问候。

于 2012-10-10T13:20:34.557 回答
2

只需让required属性取决于按下的按钮。

<h:form id="form">
    <c:set var="saveButtonPressed" value="#{not empty param['form:save']}" />
    ...
    <h:inputText ... required="#{saveButtonPressed}" />
    ...
    <h:commandButton id="save" ... />
</h:form>
于 2012-10-10T15:11:26.413 回答
0

在考虑了Bento的建议后,我意识到让它按我想要的方式工作的唯一方法是使用 AJAX a4j

我必须在我的代码中引入的更改是:

  1. h:commandButton“全选”按钮替换为a4j:commandButton.
  2. 为我的组件定义id标签h:selectOneMenu,这样我就可以通过之前定义的方式重新渲染a4j:commandButton组件。

JSF原页面修改如下:

(...)
<table>
    <tr>
        <td>
            <a4j:commandButton value="Select all opt1" action="#{MyClass.selectOpt1}"
                reRender="list1,list2,(...)" ajaxSingle="true" />
            <a4j:commandButton value="Select all opt2" action="#{MyClass.selectOpt2}"
                reRender="list1,list2,(...)" ajaxSingle="true" />
            <a4j:commandButton value="Select all opt3" action="#{MyClass.selectOpt3}"
                reRender="list1,list2,(...)" ajaxSingle="true" />
        </td>
    </tr>
    <tr>
        <td>
            <h:outputText value="List 1:" />
        </td>
        <td>
            <h:selectOneMenu value="#{MyClass.list1Val}" id="list1">
                <f:selectItems value="#{MyClass.listOfOptions}" />
            </h:selectOneMenu>
        </td>
    </tr>
    <tr>
        <td>
            <h:outputText value="List 2:" />
        </td>
        <td>
            <h:selectOneMenu value="#{MyClass.list2Val}" id="list2">
                <f:selectItems value="#{MyClass.listOfOptions}" />
            </h:selectOneMenu>
        </td>
    </tr>
(...)

非常感谢Bento的建议!

于 2012-10-10T14:51:24.510 回答