我有以下Dropdown列表,其中有一个与之关联的事件,当用户从此下拉列表中选择一个值时,其余的下拉列表以及表格都会相应地填充:
<Td>
<h:selectOneMenu id="combocarList"
value="#{customerBean.selectedcar}"
styleClass="comboStyle"
valueChangeListener="#{customerBean.loadothercombos}"
onchange="document.forms[0].submit()"
>
<f:selectItem
itemLabel="-----------Select--------------"
itemValue="None" />
<f:selectItems value="#{customerBean.carsList}" />
</h:selectOneMenu>
</Td>
我还有h:commandButton
如下:
<TD>
<h:commandButton id="btnCheckVals" value="Submit"
onclick="return checkSelectedVal(this);"
></h:commandButton>
</TD>
当我点击“提交”按钮时,将调用与上述下拉列表相关联的事件,并且永远不会调用javascript函数!是预期的行为?如果是这样我怎么能这样做,所以在事件被触发之前调用javascript函数,允许检查用户是否从下拉列表中选择了值。
答案 0 :(得分:1)
我不确定您是否在之前的一个问题上阅读了my answer。您从未提供任何反馈,您接受了另一个答案。我已经警告过这种做法是一种愚蠢的方式。
你基本上在这里滥用valueChangeListener
。其唯一目的是提供一个点,以便在同一时刻访问两者旧值和新值,以便您可以在必要时执行特定的业务操作,例如记录这两个值。
使用它的唯一目的是“自动”填充另一个组件/元素基于仅新值(你对旧值完全不感兴趣)是一个黑客攻击。如果您已经使用JSF 2.0,我非常强烈推荐链接答案中提到的<f:ajax>
方法。
回到您的具体问题,您需要了解只要提交的值与初始模型值不同,就会触发valueChangeListener
始终。这与JavaScript的所有帮助无关。 onchange="submit()"
并不专门触发侦听器,它只是将整个表单提交给服务器。它恰好发生在最终用户更改下拉列表时,因此保证更改,因此将在服务器端调用侦听器。
您的问题表明您没有在valueChangeListener
内部使用提交的值设置模型值,并且您正在调用FacesContext#renderResponse()
。这种方法几乎与我的链接答案的第一种方式所证明的相同,期望将提交的值设置为模型值的行。因为您没有设置它,所以任何后续表单提交都将因此触发监听器(因为提交的值与模型值不同!)。此外,由于FacesContext#responseComplete()
跳过调用操作阶段,因此永远不会调用操作方法。
现在,再次重新阅读我的链接答案如何正确实施它。