【问题标题】:Change listener without submitting the form在不提交表单的情况下更改侦听器
【发布时间】:2013-12-09 21:24:03
【问题描述】:

我有一个列表框,我想捕捉选择的变化,以便根据它填充另一个列表框。我尝试了以下方式:

<h:selectOneMenu id="comunitaValle" value="#{struttura.nomeComunitaDiValle}" 
     onchange="submit()" valueChangeListener="#{struttura.getComuniInComunita}">
<f:selectItems value="#{struttura.comunitaValleList}" />
</h:selectOneMenu>

它工作正常,但是在这个页面中还有其他参数标记为

required="true"

当提交表单时,我会收到控制这些字段已设置的错误消息。如何避免提交整个表单以避免这种情况发生并且仍然在 2 个列表框上保持正确的行为?

编辑:

根据https://stackoverflow.com/a/4802483/2492962,我已经找到了一种解决方案(不知道是不是最好的):

<h:selectOneMenu id="comunitaValle" value="#{struttura.nomeComunitaDiValle}" 
      valueChangeListener="#{struttura.getComuniInComunita}" immediate="true">
<a4j:support event="onchange" reRender="cap"/>
<f:selectItems value="#{struttura.comunitaValleList}" />
</h:selectOneMenu>

可以吗? JBoss 显示警告消息:

INFO  [lifecycle] WARNING: FacesMessage(s) have been enqueued, but may not have been displayed.

但刷新似乎没问题。

【问题讨论】:

  • 您使用的是 JSF-2 还是提供 AJAX 功能的工具包?因为这听起来像是它的标准用例。
  • 是的,但我无法做到这一点。有什么建议吗?
  • 以上更正:OP 根本没有使用 JSF 2.x。
  • 关于您的编辑:您是否尝试在 getComuniInComunita 中显示 FacesMessages?
  • getComuniInComunita 根据第一个中的选择项填充另一个下拉列表。此处不应显示任何 FacesMessage。我在这个页面里有一些FaceMessages,表明还有一些其他的字段还没有填写。这些是我在第一篇文章中试图解释的“我的错误消息”,我不希望在选择下拉列表中的项目后显示这些消息。

标签: ajax jsf richfaces jsf-1.2


【解决方案1】:

根据https://stackoverflow.com/a/4802483/2492962,我已经找到了一种解决方案(不知道是不是最好的):

<h:selectOneMenu id="comunitaValle" value="#{struttura.nomeComunitaDiValle}" 
      valueChangeListener="#{struttura.getComuniInComunita}" immediate="true">
<a4j:support event="onchange" reRender="cap"/>
<f:selectItems value="#{struttura.comunitaValleList}" />
</h:selectOneMenu>

<h:selectOneMenu id="cap" value="#{struttura.cap}"  >
<f:selectItems value="#{struttura.comuneIstatCapList}" />
</h:selectOneMenu>

【讨论】:

  • 终于找到了关于它的规范文章:balusc.blogspot.de/2007/10/populate-child-menus.html - 我会说继续你的解决方案,但请阅读文章以了解潜在的陷阱。
  • 太棒了! FacesContext.getCurrentInstance().renderResponse();是我一直在寻找的答案!谢谢!
【解决方案2】:

假设你的 JSF 看起来像这样:

<h:selectOneMenu id="comunitaValle" value="#{struttura.nomeComunitaDiValle}">
   <f:ajax listener="#{struttura.getComuniInComunita}" 
           execute="@this" render="myListBox" />   
   <f:selectItems value="#{struttura.comunitaValleList}" />
</h:selectOneMenu>

<h:selectManyListbox id="myListBox" value="#{struttura.backingValueList}">
   <f:selectItems value="#{struttura.listBoxValues}" var="val" 
                  itemLabel="#{val.name}" />
</h:selectManyListbox>

然后,您的支持 bean 需要一个接受 javax.faces.event.AjaxBehaviorEvent 参数的方法 getComuniInComunita(有关详细信息,请参阅 reference)。

execute 属性将导致 JSF 仅在调用 listener 方法之前更新/验证选择菜单。由于您的选择菜单仅控制列表框,因此您可以在侦听器方法完成后提供特定的组件 id 进行更新。

【讨论】:

  • 调用 public void getComuniInComunita(AjaxBehaviorEvent event) 时出现 java.lang.ClassNotFoundException: javax.faces.event.AjaxBehaviorEvent
  • @user2492962 嗯,你在使用 JSF-2 吗?如果没有,您使用哪个工具包来获得 ajax 支持?
  • 嗯..也许不是..我刚刚找到了这个 jsf-facelets-1.1.15.B1
  • FacesContext.class.getPackage().getImplementationVersion();返回 1.2_12-b01-FCS,但编译正确;问题是运行时。
  • @user2492962 您的编译时类路径中可能有一个 JSF2 API jar,但没有将其部署到您的应用服务器。
【解决方案3】:

这是 JSF1.2 的解决方案,使用 Richfaces3.3 &lt;a4j:support&gt;

<a4j:region>
  <h:selectOneMenu id="comunitaValle" value="#{struttura.nomeComunitaDiValle}">
     <a4j:support event="onchange" action="#{struttura.getComuniInComunita}" 
             ajaxSingle="true" reRender="myListBox" limitToList="true" />   
     <f:selectItems value="#{struttura.comunitaValleList}" />
  </h:selectOneMenu>

  <h:selectManyListbox id="myListBox" value="#{struttura.backingValueList}">
     <f:selectItems value="#{struttura.listBoxValues}" var="val" 
                    itemLabel="#{val.name}" />
  </h:selectManyListbox>
</a4j:region>

这是我最接近复制 JSF-2 的方法。 &lt;a4j:region&gt; 使我们能够将处理限制为页面的子集(类似于 JSF-2 中的 execute 属性)。

此外,您可能会发现 Richfaces architecture overview 很有帮助。

【讨论】:

  • 找不到 的 limitRender 属性。此外,这个解决方案给了我一个例外:org.apache.jasper.el.JspMethodNotFoundException。如果 getComuniInComunita return 无效,会不会有问题?
  • 抱歉,limitRender 在 RF3 中被称为 limitToList,我已经在答案中更改了它。我不确定方法未找到异常。我将 Jboss EL 与 RF3 一起使用,它绕过了以前 EL 版本的限制。因此很可能您需要符合docs 中的确切签名,这需要Object 返回值。
  • 似乎仍然找不到我的方法。如果没有错误,我自己的解决方案似乎更适合。有什么问题吗?
猜你喜欢
  • 2014-12-31
  • 1970-01-01
  • 1970-01-01
  • 2014-08-09
  • 2021-02-15
  • 1970-01-01
  • 2019-09-17
  • 1970-01-01
  • 2011-07-09
相关资源
最近更新 更多